flawopen.com/command-injection/C-cpp

● CWE-918 · 緊急
セキュリティ研究 · FlawOpen

脆弱性の解説: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.

💡 わかりやすい解説 (ELI5)

オフィスのアシスタントに「report.pdf」という書類の印刷を頼む場面を想像してください。攻撃者が「report.pdf; whoami」というファイル名を渡すと、アシスタントはそのメモ全体をそのまま端末の窓口に提出してしまい、書類の印刷に加えて管理者バッジの読み取りまで実行してしまいます。

主要な概念と専門用語

Web Application Security
主要概念 (Web Application Security):Core architecture component affected by CWE-918.
CWE-918
主要概念 (CWE-918):Standard Common Weakness Enumeration classification for command-injection-c-cpp.
Defense-in-Depth
主要概念 (Defense-in-Depth):Multi-layered engineering verification and runtime boundary isolation.

ステップ・バイ・ステップの攻撃フロー

Step 1

信頼できない入力の受信

アプリケーションがHTTPリクエストから診断用ホスト名やファイル名などの入力を直接受け取ります。

Step 2

シェルコマンド文字列の安全でない連結

バックエンドが引数リストを使わず、生文字列の結合によってシェルコマンドを構築します。

Step 3

コマンド区切り文字の挿入

攻撃者が ';' や '&&'、'|'、バッククォートなどのメタ文字(例: '127.0.0.1; id')を挿入して構文を脱出します。

Step 4

サブシェルでの実行とホスト侵害

OSシェルがWebサーバー権限で追加されたコマンドを実行し、任意のリモートコード実行に至ります。

ソースコード比較:脆弱 vs 堅牢化

✕ 脆弱な実装
// 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);
}
✓ 堅牢化されたセキュアパッチ
// 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);
    }
}

エンジニアリング&システム堅牢化チェックリスト

References