説明
ユーザー入力を shell_exec、exec、system、passthru、proc_open などのOSコマンド実行APIに渡すと、コマンドインジェクションが発生するおそれがあります。
想定される影響
任意のコマンドの実行、ファイルの漏えい、権限昇格、サービスの侵害につながる可能性があります。
対処方法
可能であればシェル呼び出しをなくします。必要な場合は、許可リストによる検証と escapeshellarg を併用します。
例
変更前
php
<?php
$target = $_REQUEST['ip'];
shell_exec('ping -c 4 ' . $target);
変更後
php
<?php
$target = $_REQUEST['ip'] ?? '';
if (filter_var($target, FILTER_VALIDATE_IP) === false) {
http_response_code(400);
exit;
}
shell_exec('ping -c 4 -- ' . escapeshellarg($target));
解説:
- 変更前: 入力を
shell_execのコマンド文字列に直接連結すると、;、&&、バッククォートなどが追加のコマンドとして解釈されるおそれがあります。 - 変更後: 入力がIPアドレスであることを検証し、
--でオプションの終わりを示したうえで、引数をescapeshellargで囲みます。引用符で囲むだけでは、-fなどの値が実行するプログラムのオプションとして扱われることを防げません。