インラインJSONを安全にするためにやらなければならないことは、すべての終了</script>
文字列内のタグ。エスケープ/
お気に入り <\/script>
。
しかし、私はまだ私のページを壊す奇妙な組み合わせを見つけました。 「印刷しない」というテキストはページに出力されません。 HTMLコメントだけでも問題ありません。scriptタグだけでも問題ありませんが、この2つの組み合わせは致命的です。何故ですか?
<!DOCTYPE html>
Before
<script>"<script>"</script>
fine
<script>"<!--"</script>
still fine
<script>"<!--<a>"</script>
fine again
<script>"<!--<script>"</script>
Won't print
「元気になる前にもう一度元気元気」と表示されます。 「印刷しない」はスクリプトタグの一部として扱われ、閉じられていないものとして扱われます。
これに対する正しい答えは、「仕様のHTMLパーサーがそう言っているため」です。
通常の "スクリプトタグ内"の状態 から、HTMLコメントの開始(<!--
)は、パーサーを エスケープされた状態 にし、そのモードからスクリプト開始タグ(<script>
)を ダブルエスケープされた状態 に入れ、スクリプトの終了タグ(</script>
)は無視されます。
なぜ地球上でこれを行うのですか? JSをサポートしていないブラウザにコードを挿入するための下位互換性。 Chaalsは https://github.com/w3c/html/issues/1617 で素晴らしい答えを提供します。以前は通常のコードだった例をここに示します。
<script>
<!-- //hide from non-JS browsers
function doSomething() {
var coolScript = "<script>" + theCodeICopied + "</script>";
document.write(coolScript);
}
// And if you forget to close your comment here, things go funnny
-->
</script>
そのため、スクリプトの開始タグと終了タグの両方をエスケープしない限り、この改ページの脆弱性で立ち往生しています。
JS文字列の_
“<!--<script>”
_がXSSの脆弱性を引き起こすのはなぜですか?
余分な開き括弧 :
Franz Sedlmaierから提出されたこのXSSベクトルは、最初に開く山括弧と終わり山括弧の対応するペアを使用し、次にタグを比較するBoyer-Mooreのようなより効率的なアルゴリズムではなく、内部でタグを比較することで機能する特定の検出エンジンを無効にすることができます開始山かっこと関連するタグの文字列全体の一致(もちろん解読後)。ダブルスラッシュは、JavaScriptエラーを抑制するために、末尾の無関係なブラケットをコメントアウトします。
<<SCRIPT>alert("XSS");//<</SCRIPT>
また、そのリンクにある次の例も参照してください。「終了スクリプトタグなし」、そのような無効なコードがあると正しくない。それがページ全体であり、他に何も含まれていない場合、XSSの脆弱性はなく、何も表示されません。コメントを開いてEOFで終了しているため、何も出力されません。 doループは、条件が偽の場合でも、少なくとも1回は常に実行されます。条件がテストされる前にコードブロックが実行されるためです。 whileまでのすべてを実行し、ループするか、ループを終了します。