これは(私の意見では)意見の問題なので、この回答をCWします。インターネットの善意の市民としての私の意見は次のとおりです。
- 「サニタイズ」には大きく分けて2種類あります。1つはセマンティックサニタイズで、入力が想定どおりであることを確認します(電話番号、郵便番号、通貨額など)。もう1つは防御的なサニタイズです。これは(私の意見では)一般的に誤った、ユーザーに敵対的な活動です。
- 実際、入力は、データベースサーバー、HTMLレンダラー、JavaScriptインタープリターなど、何かに触れるまでは決して怖いものではありません。リストは長いです。
ポイント1に関しては、上記のポイント2を無視しているため、防御的なサニタイズは誤った方向に進んでいると思います。悪意のある入力から防御している環境がわからないと、入力アルファベットを大幅に制限せずに実際にサニタイズすることはできません。自分自身と戦っている可能性があります。これは、正当なユーザーがアカウントに保持したいデータを使用して実行できることを不必要に制限するため、ユーザーに対して敵対的です。「コメント」、「ニックネーム」、「メモ」の各フィールドに、XML、SQL、またはその他の言語の特殊文字のような文字を含めたいと誰が言いますか?入力をフィルタリングする意味的な理由がない場合、なぜそれをユーザーに行うのですか?
ポイント2は本当にこれの核心です。サーバー側のコード(またはクライアント側のコード)は、疑うことを知らない解釈環境に直接渡すことができるため、ユーザー入力は危険な場合があります。この環境では、それぞれの異なる環境にとって重要なメタ文字が予期しない動作を引き起こす可能性があります。手つかずのユーザー入力をクエリテンプレートに直接貼り付けてSQLに直接渡すと、悪意のあるユーザーが引用符などの特殊なSQLメタ文字を使用して、絶対に望まない方法でデータベースを制御する可能性があります。しかし、それだけでは、私の名前が「オー・ヘンリー」であると私があなたに言うのを妨げる理由はありません。
ポイント2の重要な問題は、多くの異なる解釈環境があり、ユーザー入力によってもたらされる脅威に関しては、それぞれが完全に異なることです。いくつか挙げてみましょう。
- SQL-ユーザー入力の引用符は大きな潜在的な問題です。特定のDBサーバーには、他の悪用可能な構文規則がある場合があります
- HTML-ユーザー入力がHTMLに直接ドロップされると、ブラウザーのHTMLパーサーは、スクリプトの実行、トラッカーイメージのロードなど、埋め込まれたマークアップの指示に喜んで従います。重要なメタ文字は「<」、「>」、「&」です(後者は攻撃のためではなく、それらが引き起こす混乱のためです)。ユーザー入力はHTML要素属性内に入る必要があるかもしれないので、ここでも引用符について心配するのもおそらく良いことです。
- JavaScript-ページテンプレートが実行中のJavaScriptコードにユーザー入力を直接入れる必要がある場合、心配することはおそらく引用符です(入力がJavaScript文字列として扱われる場合)。ユーザー入力を正規表現に入れる必要がある場合は、さらに多くのスクラブが必要です。
- ログファイル-はい、ログファイル。ログファイルをどのように見ますか?Linuxボックスのシンプルなコマンドラインウィンドウで実行します。このようなコマンドラインの「コンソール」アプリケーションは、一般に、カーソル位置やその他のさまざまなことを制御するために、古いASCII端末にまでさかのぼる古い「エスケープシーケンス」に従います。巧妙に作成されたユーザー入力に埋め込まれたエスケープシーケンスは、それらのエスケープシーケンスを活用するクレイジーな攻撃に使用できます。一般的な考え方は、ユーザー入力をログファイルにドロップし(おそらくページエラーログの一部として)、管理者をだましてxtermウィンドウでログファイルをスクロールさせることです。ワイルドですね
ここで重要な点は、これらの環境を不正な入力や悪意のある入力から保護するために必要な正確な手法は、人によって大きく異なるということです。SQLサーバーを悪意のある引用符から保護することは、HTMLまたはJavaScriptでそれらの引用符を保護することとはまったく異なる問題です(これらは両方とも完全に異なることに注意してください)。
結論:したがって、私の意見では、不正な入力や悪意のある入力の可能性を心配する場合の適切な注意の焦点は、ユーザーデータを読み取るのではなく、書き込むプロセスです。ユーザー提供データの各フラグメントは、各解釈環境と連携してソフトウェアによって使用されるため、「引用」または「エスケープ」操作を実行する必要があり、ターゲット環境に固有の操作である必要があります。それがどの程度正確に配置されているかは、場所によって異なる場合があります。たとえば、従来のSQLでは、プリペアドステートメントを使用しますが、プリペアドステートメントの欠陥により、そのアプローチが困難になる場合があります。HTMLを吐き出すとき、ほとんどのサーバー側フレームワークには、エンティティ表記でエスケープするHTMLまたはXML用のあらゆる種類の組み込みフックがあります(&
にとって "&")。現在、Javascriptで物事を保護する最も簡単な方法は、JSONシリアライザーを利用することですが、もちろん他の方法もあります。