外部データや入力を決して信頼しないでください
Web アプリケーションのセキュリティについて最初に認識しなければならないことは、外部データは信頼すべきではないということです。外部データには、プログラマが PHP コードに直接入力しないデータが含まれます。他のソースからのデータ (GET 変数、フォーム POST、データベース、構成ファイル、セッション変数、Cookie など) は、セキュリティを確保するための手順が講じられるまで信頼できません。
たとえば、次のデータ要素は PHP で設定されているため安全であると考えられます。
リスト 1. 安全で完璧なコード
以下は引用された内容です:
$myUsername = tmyer;
$arrayUsers = array(tmyer, tom, tommy);
define("GREETING", hello there . $myUsername);
?> ただし、次のデータ要素にはすべて欠陥があります。
リスト 2. 安全でない欠陥のあるコード
以下は引用された内容です:
$myUsername = $_POST[username] //tainted!
$arrayUsers = array($myUsername, tom, tommy ); //tainted!
define("GREETING", hello there . $myUsername); //tainted!
?>
なぜ最初の変数 $myUsername はフォーム POST からのものなのでしょうか?ユーザーはこの入力フィールドに任意の文字列を入力できます。これには、ファイルを駆除したり、以前にアップロードしたファイルを実行したりする悪意のあるコマンドも含まれます。 「A ~ Z の文字のみを受け入れるクライアント側 (JavaScript) フォーム検証スクリプトを使用すれば、この危険を回避できないのですか?」と疑問に思われるかもしれません。はい、これは常に有益なステップですが、後で説明するように、誰でも任意のフォームを自分のマシンにダウンロードして変更し、必要なものを再送信できます。
解決策は簡単です。$_POST[username] でサニタイズ コードを実行する必要があります。これを行わないと、(配列や定数などで) $myUsername を使用するたびに、これらのオブジェクトが汚染される危険があります。
ユーザー入力をサニタイズする簡単な方法は、正規表現を使用して入力を処理することです。この例では、文字のみが受け入れられることが想定されています。文字列を特定の文字数に制限したり、すべての文字を小文字にすることを要求したりすることも良いアイデアかもしれません。
リスト 3. ユーザー入力を安全にする
以下は引用された内容です:
$myUsername = cleanInput($_POST[username]) //clean! tommy); //クリーン!
define("GREETING"、こんにちは。$myUsername); //クリーン!
関数 cleanInput($input); [^a-z]/", "", $clean);
$clean = substr($clean,0,12);return $clean;
}