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 で違反を見ながら足していくと漏れを防げます。