Webからのユーザー入力をWebアプリケーションのさまざまな部分で安全に使用できるようにするための正しい方法(最も柔軟、疎結合、最も堅牢など)は何だと思いますか?もちろん、コンテキストごとにそれぞれのサニタイズ機能(データベース、画面への表示、ディスクへの保存など)を使用できますが、安全でないデータを処理して安全にするための一般的な「パターン」はありますか?適切に安全にされない限り、それを安全でないものとして扱うことを強制する確立された方法はありますか?
3 に答える
すでに述べたように、Web セキュリティについて懸念する場合、考慮すべき点がいくつかあります。考慮すべきいくつかの基本原則を以下に示します。
- ユーザーからの直接入力をクエリや変数に統合することは避けてください。
したがって、これは のようなものがないことを意味します$variable = $_POST['user_input']
。このような状況では、あまりにも多くの制御をユーザーに委ねています。入力がデータベース クエリに影響する場合は、ユーザー入力を検証するためのホワイトリストを常に用意してください。クエリがユーザー名に対するものである場合は、適切なユーザー名のリストに対して検証します。ユーザー入力をドロップインして単純にクエリを作成しないでください。
1 つの (可能性のある) 例外は、検索文字列です。この場合、簡単にサニタイズする必要があります。
- サニテーションなしでユーザー入力を保存することは避けてください。
ユーザーが他のユーザーのプロファイルを作成したり、情報をアップロードしたりする場合は、許容できるデータの種類を示すホワイト リストを用意するか、悪意のある可能性のあるものをすべて取り除く必要があります。これは、システムのセキュリティのためだけでなく、他のユーザーのためでもあります (次のポイントを参照してください)。
- ストリップせずに、ユーザーからブラウザーに何も出力しないでください。
これはおそらく、セキュリティ コンサルタントが私に強調した最も重要なことです。ユーザーが入力を受け取ったときに入力をサニタイズするだけに頼ることはできません。自分で出力を作成していない場合は、HTML 文字をエンコードするか、<plaintext>
タグでラップして、出力が無害であることを常に確認してください。ユーザー A が、そのページを表示する他のユーザーに害を及ぼすような JavaScript を少しアップロードした場合、それは開発者側の単純な過失です。すべてのユーザー出力は、すべてのブラウザーでテキストとして表示される以外に何もできないことを知っていると、夜はぐっすり眠ることができます。
- ユーザー以外がフォームを制御できるようにしないでください。
XSS は本来よりも簡単で、1 つの段落で説明するのは非常に困難です。簡単に言えば、フォームを作成するたびに、フォーム データを処理するスクリプトへのアクセス権をユーザーに与えることになります。誰かのセッションや Cookie を盗んでも、フォーム ページにいるかのようにスクリプトに話しかけることができるようになりました。期待するデータのタイプと、検索する変数名を知っています。私がユーザーであるかのようにこれらの変数を渡すだけで、スクリプトは違いを認識できません。
上記は衛生の問題ではなく、ユーザーの検証の問題です。私の最後のポイントは、この考えに直接関係しています。
- ユーザーの検証またはロールの検証に Cookie を使用しないでください。
ユーザーの Cookie を盗むことができれば、その 1 人のユーザーを不幸にする以上のことができるかもしれません。Cookie に「member」という値があることに気付いた場合、その値を「admin」に簡単に変更できます。うまくいかないかもしれませんが、多くのスクリプトでは、管理者レベルの情報にすぐにアクセスできます。
簡単に言うと、Web フォームを保護するための簡単な方法は 1 つではありませんが、実行すべきことを単純化する基本原則があり、スクリプトを保護するストレスを軽減します。
適切な測定のためにもう一度:
- すべての入力をサニタイズする
- すべての出力をエンコードする
- 厳密なホワイトリストに対して実行に使用される入力を検証します
- 入力が実際のユーザーからのものであることを確認してください
- ユーザーベースまたはロールベースの検証をブラウザー側/ユーザーが変更可能にしないでください
また、誰かのリストが網羅的または完全であると思い込まないでください。
私は、このような汎用フレームワークが存在し、プログラミング言語よりも単純であることに少し懐疑的です。
「安全」の定義は層によって大きく異なる
- 入力フィールドの検証、数字、日付、リスト、郵便番号、車両登録
- クロス フィールド検証
- ドメインの検証 - それは有効な検針値ですか? ミス・ジョーンズは今月 3 億ポンドの電気を使いましたか?
- 相互リクエスト検証 - 同じ日に 2 つの大西洋横断フライトを本当に予約していますか?
- データベースの一貫性、外部キーの検証
- SQL インジェクション
また、違反が発覚した場合の対応についても検討してください。
- UI レイヤーでは、数値フィールドから数字以外の chras を静かに削除するだけでなく、UI エラーを発生させます。
- UI では、おそらくすべてのフィールドを検証し、個々のエラーにフラグを立てたいと考えています。
- 他のレイヤーでは、例外をスローしたり、ビジネス プロセスを開始したりする可能性があります
おそらく私はあなたのビジョンを見逃していますか?あなたが考えているものに近いものを見たことがありますか?
単一の方法を使用してすべての用途のデータをサニタイズすることはできませんが、良いスタートは次のとおりです。
- Filter_Varを使用して検証/サニタイズします
Filter Varは、さまざまな種類のデータを取得し、不正な文字(数字であると予想されるものの非数字など)を取り除き、有効な形式(IPアドレス)であることを確認します。
注:メールアドレスはFilter_Varの実装よりもはるかに複雑なので、適切な機能を求めてGoogleを利用しています。
- Mysqlデータベースに何かを入力する前にmysql_real_escape_stringを使用してください
データベースにデータを入力するまで、これを使用することはお勧めしません。とにかく、準備されたmysqliステートメントを使用する方がおそらく良いでしょう。