ガイドの冒頭で、データ フィルタリングは、あらゆる言語およびあらゆるプラットフォームにおける WEB アプリケーション セキュリティの基礎であると述べました。これには、アプリケーションとの間で入力されるデータの検証が含まれます。優れたソフトウェア設計は、開発者が
データ フィルタリングを回避できないことを確認し、
違法な情報が合法的な情報に影響を与えないことを確認し、
データのソースを特定するのに役立ちます。
データ フィルタリングをバイパスできないようにする方法についてはさまざまな見解があり、そのうちの 2 つは他の見解よりも一般的であり、より高いレベルの保証を提供します。
スケジュール方法 この方法は、単一の PHP スクリプト (URL 経由) でスケジュールされます。他の操作は、必要に応じて include または require を使用して含められます。このアプローチでは通常、各 URL にディスパッチ用の個別の GET 変数を渡す必要があります。この GET 変数は、スクリプト名を置き換える、より単純化された設計と考えることができます。例:
http://example.org/dispatch.php?task=print_formdispatch.phpは唯一のルート ファイル (ドキュメント ルート) です。これにより、開発者は 2 つの非常に重要な作業を行うことができます。1 つは
最初に dispatch.php にグローバル セキュリティ処理を実装すること、もう 1 つはこれらの処理がバイパスできないようにすることです。
特に一部の特殊な目的の制御フロー操作では、データ フィルタリングが必要な場所を判断するのは簡単です。
dispatch.php スクリプトの詳細については、次の例を参照してください:
<?php/* Global Security Handling*/switch ($_GET['task']){case 'print_form':include '/inc/presentation/form.inc '; ブレーク;case 'process_form':$form_valid = false;include '/inc/logic/process.inc';if ($form_valid){include '/inc/presentation/end.inc';}else{include '/ inc/presentation/form.inc';}break;default:include '/inc/presentation/index.inc';break;}?>これが公的にアクセス可能な唯一の PHP スクリプトである場合、このプログラムが設計されていると確信できます。初期のグローバル セキュリティ処理がバイパスできないようにします。また、開発者は特定のタスクの制御フローを簡単に確認できます。たとえば、コード全体を閲覧しなくても簡単にわかります。$form_valid が true の場合、end.inc は process.inc がインクルードされる前であり、false に初期化されたばかりであるため、ユーザーに表示される唯一のものです。 process.inc の内部ロジックによって true に設定されると判断できます。それ以外の場合は、フォームが再度表示されます (関連するエラー メッセージが表示される可能性があります)。
(dispatch.php の代わりに) Index.php などのディレクトリ ディレクティブ ファイルを使用する場合は、 http://example.org/?task=print_formのような URL アドレスを使用できることに注意してください。
ApacheForceType リダイレクトまたは mod_rewrite を使用して URL アドレスhttp://example.org/app/print-form を調整することもできます。
メソッドを組み込むもう 1 つの方法は、すべてのセキュリティ処理を担当する単一のモジュールを使用することです。このモジュールは、すべてのパブリック PHP スクリプトの先頭 (または最先頭) に含まれています。次のスクリプトを参照してください security.inc
<?phpswitch ($_POST['form']){case 'login':$allowed = array();$allowed[] = 'form';$allowed[] = 'username' ; $allowed[] = 'パスワード';$sent = array_keys($_POST);if ($allowed == $sent){include '/inc/logic/process.inc';}break;}?>この場合、送信された各フォームにはフォームの一意の検証値が含まれているとみなされ、security.inc はフィルタリングが必要なフォーム内のデータを個別に処理します。この要件を実装する HTML フォームは次のとおりです:
<form action="/receive.php" method="POST"><input type="hidden" name="form" value="login" /><p>Username : <input type="text" name="username" /></p><p>パスワード:<input type="password" name="password" /></p><input type="submit" / > </form>$allowed という配列は、フォームが処理される前に、どのフォーム変数が許可されているかを確認するために使用されます。プロセス制御は何を実行するかを決定し、実際のフィルター処理されたデータは process.inc に到着します。
security.inc が常にすべてのスクリプトの先頭に含まれるようにするより良い方法は、auto_prepend_file 設定を使用することです。
フィルタリングの例 ホワイトリストの作成は、データのフィルタリングにとって非常に重要です。遭遇するすべてのフォーム データの例を示すことは不可能なので、いくつかの例は一般的な理解を助けることができます。
次のコードは電子メール アドレスを検証します:
<?php$clean = array();$email_pattern = '/^[^@s<&>]+@([-a-z0-9]+.) +[ az]{2,}$/i';if (preg_match($email_pattern, $_POST['email'])){$clean['email'] = $_POST['email'];}?> 以下のコード$_POST['color'] の内容が赤、緑、または青であることを確認します:
<?php$clean = array();switch ($_POST['color']){case 'red':case 'green ' :case 'blue':$clean['color'] = $_POST['color'];break;}?>次のコードは、$_POST['num'] が整数であることを確認します:
<?php$ clean = array ();if ($_POST['num'] == strval(intval($_POST['num']))){$clean['num'] = $_POST['num'];} >以下コードは $_POST['num'] が float であることを確認します:
<?php$clean = array();if ($_POST['num'] == strval(floatval($_POST['num ']))){ $clean['num'] = $_POST['num'];}?> 各例では、名前変換の前に配列 $clean を使用します。これは、開発者がデータが侵害される可能性があるかどうかを判断するための良い方法です。 データを検証した後は、決して $_POST または $_GET にデータを保存しないでください。開発者は、スーパー グローバル配列に保存されたデータを常に完全に疑う必要があります。
$clean を使用すると、何がフィルターされていないのかを考えるのに役立ち、ホワイトリストの役割に似ていることを付け加えておきます。セキュリティレベルを向上させることができます。
検証済みのデータのみを $clean に保存する場合、データ検証における唯一のリスクは、フィルターされていない危険なデータではなく、参照している配列要素が存在しないことです。
タイミング PHP スクリプトの実行が開始されると、すべての HTTP リクエストが終了したことになります。この時点では、ユーザーがスクリプトにデータを送信する機会はありません。したがって、(register_globals がオンになっている場合でも) スクリプトにデータを入力することはできません。このため、変数を初期化することは非常に良い方法です。