CSPは初期レンダリング中にのみ適用されますか?つまり、ドキュメントのロード後に継続的なカバレッジはありませんか?これが私が話していることの例です:
あなたのページ_example.com
_に、urlパラメータname
を取り、それをページにレンダリングするJSがあるとします。
_<script nonce="test123">
$(document).ready(function() {
$("#id").html(nameParameterTakenFromURLWithoutSanitation);
});
</script>
_
私のテストに基づいて、誰かがexample.com?name=<script>alert('XSS');</script>
にアクセスした場合、CSPに関係なく、スクリプトは引き続き実行されます(アラートをポップアップします)。最初のサーバー応答内に存在する不正なスクリプトのみがブロックされます。
Nonceを使用した "厳密な" CSPアプローチを使用しています。これが私が使用しているポリシーです:
_object-src 'none';
script-src 'nonce-test123' 'unsafe-inline' 'unsafe-eval' 'strict-dynamic' https: http:;
report-uri http://localhost:8080/csp-collector
_
スクリプトがブロックされないのはなぜですか?
CSPは、ページが最初にロードまたはレンダリングされているときだけでなく、ページ上にいる限り、ブラウザーによって強制される必要があります。他のすべてはそれを全く歯のないものにします。
したがって、発生している動作は、スクリプトが読み込まれたときとは関係ありません。代わりに、whatがロードすることについてです。 2つの問題があります。
Mozilla に説明させてください:
Strict-dynamicディレクティブは、マークアップに存在するスクリプトにnonceまたはハッシュを付加することによって明示的に与えられた信頼が、そのルートスクリプトによってロードされたすべてのスクリプトに伝達されることを指定します。
そのため、ナンスを指定してスクリプトを信頼すると、他のスクリプトが読み込まれる可能性があります。つまり、ナンスのあるスクリプトにDOM XSSの脆弱性がある場合、CSPはあなたを救いません。解決策は_'strict-dynamic'
_を削除することです(ただし、この機能に依存している場合は、もちろん問題が発生します)。
スクリプトをロードするには、jQuery .html()
を使用します。 jQueryソースコード (正確には343行目)のどこかで、古き良きeval()
を呼び出します。
したがって、コードを実行すると
_$(".test").html("<scr" + "ipt>alert('XSS');</scr" + "ipt>");
_
jQueryは何らかの理由で(理由を聞かないでください。私はソースコードを試してみましたが、失敗しました)次を実行します。
_eval("alert('XSS');");
_
これは、CSPが適用されなくなったことを意味します。新しいスクリプトタグを作成していないので、文字列を評価しています。
ここでの解決策は、CSPから_'unsafe-eval'
_を削除することですが、jQueryが壊れます。その解決策は、jQuery 3にアップグレードすることかもしれません。ソースをざっと調べたところ、これは修正されたようです。
これは、フォーム上のすべてのコード(jQuery 2を使用)が
_x.html(unsafeFromURL);
_
cSPが設定されている場合でも、XSSに対して脆弱である可能性があります。これは多くの人にとって予想外のことだと思います(私にとっては)。ただし、これは別の重要な点を思い出させるものです:XSSに対する唯一の防御線としてCSPを使用しないでください。
また、これはCSPの動作に関する問題ではなく、jQueryの動作に関する問題であることにも注意してください。
この例では、まず、CSPのインラインスクリプトと評価保護を無効にします。これらは、主要な2つのセキュリティコントロールです。特にXSSを防ぐ主な方法であるインラインのもの。
次に、<script>
タグをページに書き込むスクリプトを実行して、ページに配置します。サーバー側のコードを使用してページに同じスクリプトタグを手動で書き込んだ場合、同じ結果が得られます。 JavaScriptでそれを実行したという事実は、ここではほとんど関係ありません。
CSPの主要な保護機能を無効にすることで、XSSに対するすべての保護を削除し、XSSを取得しました。
質問のタイトルに答えるには、いいえ。まったく異なるURLにアクセスしない限り、CSPはHTMLドキュメント/リソースの存続期間を通じて適用されます。
スクリプトをサポートするブラウザーとサポートしないブラウザーにstrict-dynamic
が存在するためにスクリプトがブロックされない理由は、unsafe-inline
がブロックされない原因となります。
strict-dynamic
をサポートするブラウザの場合を見てみましょう:
Strict-dynamicの主な目的は、ホワイトリスト(JSONPなどのためにそれほど安全ではありません。 here を参照)を削除し、多くの場合に実行されるスクリプトの動的ロードを許可することですのAPIがウェブ上に公開されています。
基本的に、スクリプトタグを作成してスクリプトを動的にロードする場合、ノンスを使用しているとブロックされます。したがって、strict-dynamicが実行するのは、nonceがあり信頼されているスクリプトが、このようなスクリプトを動的にロードできる(スクリプトタグの作成)場合です。
したがって、あなたの場合:
<script nonce="test123">
$(document).ready(function() {
$("#id").html(nameParameterTakenFromURLWithoutSanitation);
});
</script>
NameParameterが次のようである場合にスクリプトタグを作成します:<script>alert('XSS');</script>
したがって、strict-dynamic
の定義により、実行する必要があります。
ここでの主な関心事は、なぜ.html()
を使用しているのかということです。名前にHTMLマークアップがあると思いますか?そうでない場合は、HTMLマークアップをエスケープし、XSSを防ぐ.text()
を使用します。