Remote Code Execution from Unbounded scanf Input in stdio Parsing

Critical Risk Memory Safety
cscanfbuffer-overflowrcestdioinput-validationstack-overflowmemory-corruption

What it is

A critical memory safety vulnerability where C code uses scanf family functions with unbounded format specifiers like %s without width limits, enabling stack buffer overflow attacks. When scanf reads input without enforcing buffer boundaries, attackers can provide input larger than the allocated buffer, overwriting adjacent memory including return addresses, function pointers, and other critical data structures. This can lead to arbitrary code execution, privilege escalation, or complete system compromise.

#include <stdio.h>
#include <string.h>

// VULNERABLE: Unbounded scanf allows buffer overflow
void login() {
    char username[32];
    char password[32];
    
    printf("Username: ");
    scanf("%s", username);  // BUFFER OVERFLOW!
    
    printf("Password: ");
    scanf("%s", password);  // BUFFER OVERFLOW!
    
    if (strcmp(username, "admin") == 0 && 
        strcmp(password, "secret") == 0) {
        printf("Access granted\n");
    } else {
        printf("Access denied\n");
    }
}
#include <stdio.h>
#include <string.h>

// SECURE: Width-limited scanf prevents overflow
void login() {
    char username[32];
    char password[32];
    
    printf("Username: ");
    scanf("%31s", username);  // Max 31 chars + null
    
    printf("Password: ");
    scanf("%31s", password);  // Max 31 chars + null
    
    if (strcmp(username, "admin") == 0 && 
        strcmp(password, "secret") == 0) {
        printf("Access granted\n");
    } else {
        printf("Access denied\n");
    }
}

💡 Why This Fix Works

The vulnerable code uses unbounded %s format specifiers, allowing buffer overflow attacks. The secure version uses %31s to limit input to 31 characters (plus null terminator) for 32-byte buffers, preventing overflow.

Why it happens

Using scanf with %s format specifier to read strings into fixed-size buffers without specifying maximum field width.

Root causes

Unbounded String Input with scanf

Using scanf with %s format specifier to read strings into fixed-size buffers without specifying maximum field width.

Multiple scanf Calls Creating Complex Overflow Scenarios

Multiple consecutive scanf calls that can be exploited in combination to create complex buffer overflow scenarios.

Missing Width Specifiers in Format Strings

Failing to specify width limits in scanf format strings, allowing arbitrarily long input.

Fixes

1

Use Width-Limited Format Specifiers

Always specify maximum field width in scanf format strings (e.g., %31s for a 32-byte buffer).

2

Replace scanf with fgets

Use fgets() with a specified buffer size instead of scanf for reading strings.

3

Enable Compiler Stack Protection

Compile with -fstack-protector-all to detect buffer overflows at runtime.

Detect This Vulnerability in Your Code

Sourcery automatically identifies remote code execution from unbounded scanf input in stdio parsing and many other security issues in your codebase.