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