web-dev-qa-db-ja.com

このJSONエンコーディングはCDATAインジェクションに対して脆弱ですか?

jsfiddle.netで生成されたページ で奇妙な表記に遭遇しました

<script type='text/javascript'>//<![CDATA[ 
$(window).load(function(){
$('form, table').animate({
    opacity: 1
});
});//]]>  

</script>

JSONデータをスクリプトに直接フィードすることがあります。私は個人的にはCDATA表記を使用していませんが、攻撃者がCDATA表記を挿入して悪影響を及ぼす可能性があるかどうかを確認したいと思います。

すべてのルール に従う標準のJSON stringifierを介してオブジェクトを実行し、</scriptを_ではなく<\/scriptに置き換えます敏感。これで十分ですか?

2
Bryan Field

_//<![CDATA[_ハックは、HTMLとXMLの両方として解析する必要があるXHTMLページで使用されます。

HTML解析ルールでは、_<script>_および_<style>_は特別な「CDATA要素」であり、次の_</_シーケンス(HTML4)または_</script_シーケンス(HTML5)までの内容は次のとおりです。生データなので、if (x<y)はエンコードなしで書き込むことができます。これはXMLパーサーを汚します。

XML構文解析ルールには特別な要素がないため、同じステートメントをif (x&lt;y)として記述する必要があります。これはHTMLパーサーを汚します。

_<_をエスケープせずに記述し、XMLパーサーとHTMLパーサーの両方に同じ意味を持たせるには、スクリプトをXML CDATAセクションにラップし、JavaScriptで非表示にすることにより、HTMLパーサーを奇妙な構成から保護できます。コメント。

この構成を使用して、エスケープせずにこれらの文字を文字列リテラルに含めることができる場合は、シーケンス_</_(HTMLの場合)と_]]>_(の両方をエスケープする必要があるため、それだけでは不十分です。 XMLの場合)。 JS文字列リテラルでこれらのシーケンスをエスケープする1つの方法は、常に_<>&_文字をそれぞれ_\x3C_、_\x3E_および_\x26_にエンコードすることです。 CDATAセクションが必要です。

すべてのルールに従う標準のJSON文字列指定子を使用してオブジェクトを実行してから、_</script_を_<\/script_に置き換えます。大文字と小文字は区別されません。これで十分ですか?

必ずしも。

  1. HTML構文。上記のように、_<\/script_はHTMLでは問題ありませんが、XHTMLでは問題です。

  2. JavaScript構文。 JSONの設計には不幸な見落としがあるため、JSONでは有効だがJavaScriptでは無効なUnicode制御文字がいくつかあります。

特に、文字U + 2028およびU + 2029、改行として機能する行と段落の区切り文字。文字列リテラルの途中に改行を挿入すると、構文エラーが発生する可能性があります(文字列リテラルが終了していません)。

JS文字列リテラルでは無効となるはずの制御文字が他にもありますが、実際にはブラウザを壊しません。

JSONエンコーダーがすべての非ASCII文字を習慣的にエンコードする場合、これは問題になりません。

埋め込まれたJSエンコーディングを正しく行う代わりに、インラインスクリプトを完全に避け、データをHTMLページ(通常のHTMLエスケープルールが適用される場所)に配置し、DOMメソッドを使用してリンクされたスクリプトからデータを取得します。

6
bobince

短い答えですが、文字<および>をグローバルに\u003cおよび\u003eに置き換えると、HTML <script>要素に安全に埋め込むことができ、有効なJSONで実行できますそれを壊すことなく。

XMLに埋め込むには、JSONにXMLで表示できる文字のみが含まれていることを確認する必要があります。具体的には、XMLには 非制御文字 のみを含めることができるため、そのような文字は\u....でエスケープする必要もあります。


http://code.google.com/p/json-sanitizer/ はJSONのような入力を受け取り、有効なJSONであり、HTML <script>要素に安全に埋め込むことができる出力を生成しますおよびXML <![CDATA[...]]>セクション内。

JSONのようなコンテンツを指定して、それを有効なJSONに変換します。

これは、データパイプラインの両端に接続して、Postelの原則を満たすのに役立ちます。

自分の行動を保守的にし、他人から受け入れることを寛大にする

他の人からのJSONのようなコンテンツに適用すると、使用するすべてのパーサーを満たす必要がある整形式のJSONが生成されます。

送信する前に出力に適用すると、エンコードの小さな間違いが強制され、JSONをHTMLおよびXMLに簡単に埋め込むことができます。

出力

出力は、RFC 4627で定義されている整形式のJSONです。出力は、3つの追加プロパティを満たします。

  1. 出力には部分文字列(大文字と小文字を区別せず)"</script"が含まれないため、さらにエンコードせずにHTMLスクリプト要素内に埋め込むことができます。
  2. 出力には部分文字列"]]>"が含まれないため、さらにエンコードせずにXML CDATAセクション内に埋め込むことができます。
  3. 出力は有効なJavascript式であるため、Javascriptのeval組み込み(括弧で囲まれた後)またはJSON.parseによって解析できます。具体的には、JS改行が埋め込まれた文字列リテラル(U + 2028段落区切り文字またはU + 2029行区切り文字)は出力に含まれません。

安全保障

出力は整形式のJSONであるため、evalに渡しても副作用や自由変数はありません。そのため、コードインジェクションベクトルも、シークレットの引き出し用のベクトルもありません。

このライブラリは、JSON文字列→JavaScriptオブジェクトフェーズに副作用がなく、無料の変数を解決しないことを保証するだけで、他のクライアント側コードが結果のJavaScriptオブジェクトを後で解釈する方法を制御できません。したがって、クライアント側のコードが、攻撃者によって制御されている解析済みデータの一部を取り、evalinnerHTMLなどの強力なインタープリターを介してそれを渡す場合、そのクライアント側のコードは意図しない影響を受ける可能性があります副作用。

3
Mike Samuel