IdeaValue

Content-Security-Policy(CSP)の設定方法:Report-Only から始める

執筆:IDEAVALU運営 · 更新:

CSP は、ページが読み込んでよいスクリプトや画像の取得元を、ブラウザに伝える仕組みです。万一 XSS(不正なスクリプトの埋め込み)が起きても、許可していない場所のスクリプトは実行されません。

まず Report-Only で試す

いきなり Content-Security-Policy を付けると、許可し忘れた外部サービス(アクセス解析、決済、地図など)が止まって画面が壊れることがあります。Content-Security-Policy-Report-Only で付けると、ブロックはせず、違反がブラウザのコンソールに表示されます。違反がなくなってから本番の Content-Security-Policy に切り替えます。

'unsafe-inline' を script-src に入れない

script-src に 'unsafe-inline' を入れると、HTML に直接書かれたスクリプトがすべて実行できてしまい、XSS への効果がほぼなくなります。インラインスクリプトが必要な場合は、リクエストごとに発行する nonce(使い捨ての値)か、スクリプトのハッシュを指定します。

Next.js(App Router)では、middleware で nonce を発行してヘッダーに入れる方法が公式ドキュメントの「Content Security Policy」の項で紹介されています。

自分で確認する方法

ヘッダーが付いているかは curl で、違反はブラウザの開発者ツールのコンソールで確認できます。

CSP が付いているか

curl -sI https://example.com | grep -i content-security-policy

直し方

CSP(読み込み元の制限)

Content-Security-Policy で、スクリプトを読み込める場所を絞ります。いきなり強制すると画面が壊れることがあるので、まず Report-Only で試します。

まず違反を記録するだけの設定で試す

Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self' https:; frame-ancestors 'self'

ブラウザの開発者ツールのコンソールで違反を確認し、使っている外部サービス(Google Analytics、Supabase など)のドメインを追加してから、Content-Security-Policy に切り替える。

Next.js でインラインスクリプトを使う場合は、middleware で nonce を発行する方法が公式ドキュメント(Content Security Policy の項)にあります。'unsafe-inline' を script-src に入れると効果がほぼなくなります。

よくある質問

Google Analytics や Stripe を使っていても CSP は設定できますか?
設定できます。各サービスが案内している CSP 用のドメインを script-src や connect-src、frame-src に追加します。Report-Only で違反を見ながら足していくと漏れを防げます。
CSPの設定方法|Content-Security-Policy を安全に導入する手順 | IDEAVALU