CSP(Content Security Policy)バイパスの可能性を調べる
Apr 10, 2022 09:45 · 2086 words · 5 minute read
CSP(Content Security Policy)がバイパスされてしまう可能性について調べたのでメモ書きを残しておきます。
目次
CSP(Content Security Policy)とは?
コンテンツセキュリティポリシー (CSP) は、クロスサイトスクリプティング (XSS) やデータインジェクション攻撃などのような、特定の種類の攻撃を検知し、影響を軽減するために追加できるセキュリティレイヤーです。
(中略)
CSP を有効にするには、ウェブサーバーから Content-Security-Policy HTTP ヘッダーを返すように設定する必要があります。
コンテンツセキュリティポリシー (CSP) - HTTP | MDN (mozilla.org) より一部抜粋
CSPには「ホワイトリスト方式」「nonce方式」「ハッシュ方式」があります。
ホワイトリスト方式
スクリプトの読み込みと実行ができるドメインをホワイトリスト方式で指定します。
しかし、著名なWebサービスのドメインであったとしても攻撃に悪用されてしまう可能性があるため、ホワイトリスト方式だけで完全な防御を実現することは難しいという課題がありました。
ハッシュ方式
実行したいスクリプトのハッシュ値を求め、レスポンスヘッダの「Content-Security-Policy: script-src」で実行を許可するハッシュ値を指定します。
nonce方式
前述のホワイトリスト方式はCSP Level 2で主に使われている方法です。Level3では更に柔軟で堅牢に対応できるnonce方式が使えるようになりました。
nonce方式では、レスポンスヘッダで指定した「Content-Security-Policy: script-src」で指定したnonceと呼ばれる文字列を持つスクリプトタグのみスクリプトを実行することができます。
例
レスポンスヘッダ
Content-Security-Policy: script-src 'nonce-2726c7f26c'
レスポンスボディ:
<script nonce="2726c7f26c">
var inline = 1;
</script>
昨今のWebアプリで広く使われているReactやVueなどのJavaScriptフレームワークでは、フレームワークが動的にスクリプトタグやコンテンツを生成します。そのため、全てのスクリプトタグにnonceを設定するのは現実的ではありません。
この問題を解決する方法として「strict-dynamic」が追加されました。「strict-dynamic」を使うことで、nonceが設定されているスクリプトタグから読み込まれたスクリプトも実行することができます。
‘strict-dynamic’ ソース式は、マークアップ中のスクリプトに明示的に与えられた信頼が、ノンスやハッシュを伴って、そのルートスクリプトによって読み込まれるすべてのスクリプトに伝搬されることを指定します。同時に、 ‘self’ や ‘unsafe-inline’ のようなホワイトリストやソース表現は無視されます。
CSP: script-src - HTTP | MDN (mozilla.org) より一部抜粋
2022年4月現在、日本国内で使われているWebブラウザの多くで「strict-dynamic」が使えるようです。
“strict-dynamic” | Can I use… Support tables for HTML5, CSS3, etc
推奨CSP設定
Googleは汎用的に使えるCSP設定として、下記の内容を推奨しています。
Content-Security-Policy:
object-src 'none';
script-src 'nonce-{random}' 'unsafe-inline' 'unsafe-eval' 'strict-dynamic' https: http:;
base-uri 'none';
report-uri https://your-report-collector.example.com/
Strict CSP - Content Security Policy
Strict CSPを使った実装例
活発に開発されているフレームワークでは、フレームワーク側で「strict-dynamic」に対応してくれているようです。
Next.jsでStrict CSPを実現する - kotamat’s site
CSPのバイパス例
CSPのホワイトリスト方式で指定したドメイン上に、JSOPや古いAngularJSを使ったサービスが存在している場合、CSPをバイパスされてしまう可能性があるそうです。
Content Security Policy Level 3におけるXSS対策 - pixiv inside
CTF(Capture The Flag)というセキュリティの競技観点でのCSPバイパス手法まとめです。
その他のCSPバイパス事例です。
- Finding DOM Polyglot XSS in PayPal the Easy Way | PortSwigger Research
- Hunting nonce-based CSP bypasses with dynamic analysis | PortSwigger Research
- AngularJS CSP bypass in 56 characters | PortSwigger Research
- Bypassing CSP with policy injection | PortSwigger Research
CSPバイパスのチェックツール
下記のツールを使うことで、CSPバイパスの可能性をチェックすることができます。
CSP Evaluator (csp-evaluator.withgoogle.com)
Chrome拡張版もあります。
Chrome ウェブストア - 拡張機能 (google.com)
最後に
CSPを使って守りを固める方法を調べました。
2022年4月時点では、「フレームワークの機能を使ってStrict CSPに対応する」というのが一番良さそうです。
参照URL
- CSP (Content Security Policy) nonce-sourceについて調べてみた — A Day in Serenity (Reloaded) — PHP, CodeIgniter, FuelPHP, Linux or something (a-way-out.net)
- Content Security Policy Level 2 (w3.org)
- CSP: script-src - HTTP | MDN (mozilla.org)
- コンテンツセキュリティポリシー (CSP) - HTTP | MDN (mozilla.org)
- Content Security Policy Level 3におけるXSS対策 - pixiv inside
- Strict CSP - Content Security Policy
- Next.jsでStrict CSPを実現する - kotamat’s site
- CTFのWebセキュリティにおけるクライアント側まとめ(CSP, CORS, Web Assembly, PostMessage) - はまやんはまやんはまやん (hamayanhamayan.com)
- CSP Is Dead, Long Live CSP! On the Insecurity of Whitelists and the Future of Content Security Policy – Google Research
- Finding DOM Polyglot XSS in PayPal the Easy Way | PortSwigger Research
- Hunting nonce-based CSP bypasses with dynamic analysis | PortSwigger Research
- AngularJS CSP bypass in 56 characters | PortSwigger Research
- Bypassing CSP with policy injection | PortSwigger Research
- HTTP CSP について - Qiita