V1: エンコーディングとサニタイゼーション
管理目標
この章では、信頼できないデータの安全でない処理に関する、最も一般的な Web アプリケーションセキュリティの弱点に焦点を当てます。これは、信頼できないデータが、関連するインタプリタの構文ルールを使用して解釈され、さまざまな技術的な脆弱性につながります。
現代の Web アプリケーションでは、パラメータ化されたクエリ、自動エスケープテンプレートフレームワークなどのより安全な API を使用することが常に最善でしょう。それ以外には、出力のエンコード、エスケープ、サニタイズを注意深く実行することが、アプリケーションのセキュリティにとって重要です。
入力バリデーションは、予期しない危険なコンテンツから保護するための多層防御メカニズムとして機能します。しかし、その主な目的は、入力されるコンテンツが機能上およびビジネス上の期待に一致することを確保することであるため、これに関する要件は「バリデーションとビジネスロジック」の章にあります。
V1.1 バリデーションおよびサニタイゼーションアーキテクチャ
下記のセクションでは、セキュリティの脆弱性を回避するために、安全でないコンテンツを安全に処理するためのシンタックス固有またはインタプリタ固有の要件を示します。このセクションの要件は、この処理が行われるべき順序と場所をカバーしています。また、二重エンコーディング問題を防ぐために、データが保存されるときは常に、エンコードまたはエスケープされた状態 (HTML エンコーディングなど) ではなく、元の状態で保存されることを保証することも目的としています。
1.1.1
入力は一度だけ標準形式にデコードまたはアンエスケープされ、その形式でエンコードされたデータが期待される場合にのみデコードされ、これは入力をさらに処理する前に行われる。たとえば、入力バリデーションやサニタイゼーションの後には実行されない。
2
v5.0.be-5.6.1
1.1.2
アプリケーションはそれが意図されているインタプリタまたはインタプリタ自体によって使用される前の最終ステップとして、出力エンコーディングおよびエスケープを実行する。
2
v5.0.be-5.6.2
V1.2 インジェクション防御
潜在的に危険なコンテキストの近くあるいは隣接する場所での出力エンコーディングやエスケープは、あらゆるアプリケーションのセキュリティにとって重要です。通常、出力エンコーディングとエスケープは永続化されるのではなく、適切なインタプリタですぐに使用できるように出力を安全にするために使用されます。これをあまりに早い段階で行おうとすると、不正なコンテンツとなったり、エンコーディングやエスケープが効かなくなることがあります。
多くの場合、ソフトウェアライブラリは自動的にこれを行う安全な関数やより安全な関数を含みますが、それらが現在のコンテキストに対して正しいことを確認する必要があります。
1.2.1
HTTP レスポンス、HTML ドキュメント、XML ドキュメントの出力エンコーディングは、メッセージやドキュメント構造の変更を避けるために、HTML 要素、HTML 属性、HTML コメント、CSS、HTTP ヘッダフィールドに関連する文字をエンコードするなど、要求されるコンテキストに関連している。
1
v5.0.be-5.3.1
1.2.2
URL を動的に構築する場合、信頼できないデータはそのコンテキストに応じてエンコードされている (例: クエリやパスパラメータの URL エンコーディングや base64url エンコーディング)。安全な URL プロトコルのみが許可されるようにしている (例: javascript: や data: を許可しない)。
1
v5.0.be-5.3.13
1.2.3
出力エンコーディングまたはエスケープは、JavaScript コンテンツ (JSON を含む) を動的に構築するときに使用され、メッセージやドキュメント構造の変更を回避している (JavaScript および JSON インジェクションを回避するため)。
1
v5.0.be-5.3.3
1.2.4
データ選択またはデータベースクエリ (SQL, HQL, NoSQL, Cypherなど) がパラメータ化クエリ、ORM、エンティティフレームワークもしくは他の方法により保護されており、SQL インジェクションや他のデータベースインジェクション攻撃の影響を受けない。これはストアドプロシージャを記述する際にも関係する。
1
v5.0.be-5.3.4
1.2.5
アプリケーションが OS コマンドインジェクションに対して保護していること、およびオペレーティングシステムコールがパラメータ化された OS クエリを使用するか、コンテキストに応じたコマンドライン出力エンコーディングを使用する。
1
v5.0.be-5.3.8
1.2.6
アプリケーションが LDAP インジェクション脆弱性に対して保護している、または LDAP インジェクションを防ぐために特定のセキュリティ管理策が実装されている。
2
v5.0.be-5.3.7
1.2.7
アプリケーションは、クエリパラメータ化やコンパイル済みクエリを使用することで、XPath インジェクション攻撃から保護されている。
2
v5.0.be-5.3.10
1.2.8
LaTeX プロセッサは ("--shell-escape" フラグを使用しないなど) 安全に構成されており、LaTeX インジェクション攻撃を防ぐためにコマンドの許可リストを使用している。
2
v5.0.be-5.3.12
1.2.9
アプリケーションは正規表現内の特殊文字をエスケープ (通常はバックスラッシュを使用) し、メタ文字として誤って解釈されることを防いでいる。
2
v5.0.be-5.2.9
1.2.10
アプリケーションが CSV インジェクションや数式インジェクションから保護されている。アプリケーションは CSV コンテンツをエクスポートする際に RFC4180 2.6 および 2.7 で定義されているエスケープ規則に従う必要がある。さらに、CSV やその他のスプレッドシート形式 (xls, xlsx, odf など) をエクスポートする際に、特殊文字 ('=', '+', '-', '@', '\t' (タブ), '\00' (ヌル文字) など) がフィールド値の最初の文字である場合、シングルクォートを使用してエスケープする必要がある。
3
v5.0.be-5.3.11
注: パラメータ化クエリの使用や SQL のエスケープだけでは必ずしも十分ではありません。テーブル名やカラム名 ("ORDER BY" 句のカラム名を含む) などのクエリ部分はエスケープできません。これらのフィールドにエスケープされたユーザ作成データが含まれていると、クエリの失敗や SQL インジェクションを引き起こします。
V1.3 サニタイゼーション
信頼できないコンテンツを安全でないコンテキストで使用することに対する理想的な保護は、コンテキスト固有のエンコーディングやエスケープを使用することです。これにより、安全でないコンテンツと同じ意味を維持しながら、前のセクションで詳しく説明したように、この特定のコンテキストで安全に使用できるようになります。
これが不可能な場合、潜在的に危険な文字やコンテンツを削除するサニタイゼーションが必要になります。場合によっては入力の意味を変えてしまうかもしれませんが、セキュリティ上の理由から、選択の余地がないこともあります。
1.3.1
WYSIWYG エディタなどから取得した信頼できない HTML 入力はすべて、よく知られた安全な HTML サニタイゼーションライブラリもしくはフレームワークの機能を使用してサニタイズされている。
1
v5.0.be-5.2.1
1.3.2
アプリケーションが eval() や他の Spring Expression Language (SpEL) などの動的コード実行機能を使用しない。代替手段がない場合は、実行前に含まれるユーザ入力をサニタイズする必要がある。
1
v5.0.be-5.2.4
1.3.3
潜在的に危険なコンテキストに渡されるデータは、事前にサニタイズして、このコンテキストにとって安全な文字だけを許可したり、長すぎる入力を切り詰めるなどの安全対策を実施している。
2
v5.0.be-5.2.2
1.3.4
ユーザが提供する Scalable Vector Graphics (SVG) スクリプト可能コンテンツは、スクリプトや foreignObject を含まないなど、アプリケーションにとって安全なタグや属性 (図形描画など) のみを含むように検証またはサニタイズされている。
2
v5.0.be-5.2.7
1.3.5
アプリケーションは、マークダウン、CSS や XSL スタイルシート、BBCode などのユーザが提供するスクリプト可能コンテンツまたは式テンプレート言語コンテンツをサニタイズまたは無効化している。
2
v5.0.be-5.2.8
1.3.6
アプリケーションは、信頼できないデータをプロトコル、ドメイン、パス、ポートの許可リストに照らして検証し、そのデータを使用して別のサービスを呼び出す前に潜在的に危険な文字をサニタイズすることで、サーバサイドリクエストフォージェリ (SSRF) 攻撃から保護している。
2
v5.0.be-5.2.6
1.3.7
アプリケーションは信頼できない入力に基づくテンプレートの作成を許可しないことで、テンプレートインジェクション攻撃から保護している。代替手段がない場合、テンプレート作成中に動的に含まれるすべての信頼できない入力はサニタイズまたは厳密に確認する必要がある。
2
v5.0.be-5.2.5
1.3.8
アプリケーションは Java Naming and Directory Interface (JNDI) クエリで使用する前に信頼できない入力を適切にサニタイズし、JNDI を安全に構成して JNDI インジェクション攻撃を防いでいる。
2
v5.0.be-5.2.11
1.3.9
アプリケーションは memcache に送信する前にコンテンツをサニタイズし、インジェクション攻撃を防いでいる。
2
v5.0.be-5.2.12
1.3.10
使用時に、予期しないあるいは悪意のある方法で解決される可能性のあるフォーマット文字列は、処理される前にサニタイズされている。
2
v5.0.be-5.2.13
1.3.11
SMTP インジェクションや IMAP インジェクションから保護するため、アプリケーションがメールシステムに渡す前にユーザ入力をサニタイズしている。
2
v5.0.be-5.2.3
1.3.12
正規表現に指数関数的なバックトラッキングを引き起こす要素がないことを検証している。また、信頼できない入力をサニタイズし、ReDoS 攻撃や Runaway Regex 攻撃を軽減している。
3
v5.0.be-5.2.10
V1.4 メモリ、文字列、アンマネージドコード
以下の要件は、安全でないメモリ使用に関するリスクをカバーしており、アプリケーションがシステム言語またはアンマネージドコードを使用する場合にのみ適用されます。
場合によっては、スタックのランダム化、データ実行防止などのバッファオーバーフローの保護と警告を有効にし、安全でないポインタ、メモリ、フォーマット文字列、整数、文字列操作が見つかった場合にビルドを中断するようにコンパイラフラグを設定することで、これを実現できる可能性があります。
1.4.1
アプリケーションはメモリセーフな文字列、安全なメモリコピーおよびポインタ演算を使用して、スタック、バッファ、ヒープのオーバーフローを検出または防止する。
2
v5.0.be-5.4.1
1.4.2
整数オーバーフローを防ぐために符号、範囲、および入力のバリデーション技法が使用されている。
2
v5.0.be-5.4.3
1.4.3
動的に割り当てられたメモリとリソースが解放され、解放されたメモリへの参照やポインタが削除されるか null に設定されて、ダングリングポインタや use-after-free 脆弱性を防いでいる。
2
v5.0.be-5.4.4
V1.5 安全なデシリアライゼーション
何らかの保存または転送された表現から実際のアプリケーションオブジェクトへのデータの変換 (デシリアライゼーション) はこれまでさまざまなコードインジェクション脆弱性の原因となってきました。このような問題を回避するには、このプロセスを慎重かつ安全に実行することが重要です。
特に、プログラミング言語やフレームワークのドキュメントにおいて、デシリアライズ手法が安全でなく、信頼できないデータを安全に処理できないことが明らかになっているものがあります。使用されている各言語の各メカニズムにおいて、そのメカニズムの慎重なデューデリジェンスを実行する必要があります。
1.5.1
アプリケーションが XML パーサーを制限的な構成を使用するよう構成し、XML 外部エンティティ (XML eXternal Entity, XXE) 攻撃を防止するために外部エンティティの解決などの安全でない機能を無効にする。
1
v5.0.be-5.5.2
1.5.2
信頼できないクライアントによるデータのデシリアライゼーションでは、オブジェクトタイプの許可リストを使用したり、クライアント定義のオブジェクトタイプを制限するなど、安全な入力処理を強制してデシリアライゼーション攻撃を防いでいる。明示的に安全でないと定義されているデシリアライゼーションメカニズムは信頼できない入力では使用してはいけない。
2
v5.0.be-5.5.3
1.5.3
JSON 相互運用性の脆弱性や、さまざまな URI やファイルの解析動作がリモートファイルインクルージョン (RFI) やサーバサイドリクエストフォージェリ (SSRF) 攻撃で悪用されるような問題を回避するために、同じデータ型に対してアプリケーションで使用されるさまざまなパーサー (JSON パーサー、XML パーサー、URL パーサーなど) は一貫した方法で解析を実行し、同じエンコードメカニズムを使用する。
3
v5.0.be-5.5.5
参考情報
詳しくは以下の情報を参照してください。
デシリアライゼーションやパースの問題の詳細情報はこちらを参照してください。
Last updated
Was this helpful?