flawopen.com/command-injection-c/Cpp

CWE-918 · Critical
flawopen.com Security Research

Command Injection in C/C++

Learn how to fix Command Injection (CWE-78) in C and C++. Side-by-side vulnerable vs secure code examples for posix_spawn(), execvp(), and system() shell hazards.

💡 Plain English Explainer (ELI5)

Imagine a train operator who announces stations. If an attacker slips a note saying 'Next stop Central; derail train', command injection is the system executing the derail instruction because it didn't separate the station name from the train controls.

Core Concepts & Subsystem Terms

system() & popen()
C runtime functions that invoke /bin/sh -c with the passed string, exposing full shell metacharacter parsing.
execve() & execvp()
POSIX system calls that execute a binary directly with an array of pointer arguments, completely bypassing the shell.

Step-by-Step Attack Flow

Source Code: Flaw vs. Secure Implementation

✕ UNPATCHED FLAW
// system() invokes /bin/sh with sprintf buffer
#include <stdlib.h>
#include <stdio.h>

void ping_host(const char *user_input) {
    char buffer[256];
    // Attacker input: "127.0.0.1; reboot"
    snprintf(buffer, sizeof(buffer), "ping -c 1 %s", user_input);
    system(buffer);
}
✓ HARDENED SECURE PATCH
// fork() and execvp() execute binary directly without a shell
#include <unistd.h>
#include <sys/wait.h>

void ping_host(const char *user_input) {
    pid_t pid = fork();
    if (pid == 0) {
        // Child process: arguments are discrete pointers
        char *args[] = {"ping", "-c", "1", (char *)user_input, NULL};
        execvp("ping", args);
        _exit(1);
    } else {
        waitpid(pid, NULL, 0);
    }
}

Engineering & System Hardening Checklist

References