CSP - Content Security Policy
About 2 min read
CSP (Content Security Policy) とは、 Web ページ上で実行を許可するリソースの出所を HTTP レスポンスヘッダーで宣言するセキュリティ機構です。クロスサイトスクリプティング (XSS) の 被害を大幅に軽減する防御層として、 2012 年に W3C で標準化されました。 サーバーが「このページではこのドメインのスクリプトだけ実行してよい」とブラウザに指示することで、 攻撃者が注入した不正なスクリプトの実行をブラウザレベルでブロックします。
XSS 対策としての位置づけ
XSS 対策の基本は入力のサニタイズと出力のエスケープですが、これらは開発者のミスで 漏れが生じやすい対策です。 CSP はこれらの対策を補完する「最後の砦」として機能します。 仮にエスケープ漏れで攻撃コードが HTML に混入しても、 CSP が正しく設定されていれば ブラウザがそのスクリプトの実行を拒否します。セキュアコーディングと CSP を組み合わせることで、多層防御が実現します。
主要なディレクティブ
| ディレクティブ | 制御対象 | 設定例 |
|---|---|---|
| default-src | 他のディレクティブのフォールバック | 'self' |
| script-src | JavaScript の読み込み・実行 | 'self' 'nonce-abc123' |
| style-src | CSS の読み込み・適用 | 'self' 'unsafe-inline' |
| img-src | 画像の読み込み元 | 'self' data: https://cdn.example.com |
| connect-src | fetch / XHR / WebSocket の接続先 | 'self' https://api.example.com |
| frame-ancestors | iframe での埋め込み許可元 | 'none' |
| form-action | フォームの送信先 | 'self' |
nonce ベースと hash ベースの許可方式
インラインスクリプトを許可する方法として、 nonce 方式と hash 方式の 2 つがあります。
サーバーがリクエストごとにランダムな値 (nonce) を生成し、 CSP ヘッダーと script タグの両方に同じ値を埋め込む。一致するスクリプトだけが実行される。 動的なページに適しており、 Next.js や Rails などのフレームワークが nonce の自動生成をサポートしている。
インラインスクリプトの内容から SHA-256 等のハッシュ値を算出し、 CSP ヘッダーに 記載する。スクリプトの内容が 1 バイトでも変わるとハッシュが一致せず実行されない。 静的なスクリプトに適しているが、内容を変更するたびにハッシュの再計算が必要。
report-uri / report-to によるモニタリング
CSP にはポリシー違反をサーバーに報告する仕組みが備わっています。report-uri (旧仕様) または report-to (新仕様) ディレクティブで レポート送信先を指定すると、ブラウザがポリシー違反を検知するたびに JSON 形式のレポートを 送信します。まずは Content-Security-Policy-Report-Only ヘッダーで レポートのみ収集し、既存の機能を壊さないことを確認してから本番適用に移行するのが 安全な導入手順です。
CSP 導入のフロー
導入時のよくある失敗
インラインスクリプトが動かないからと 'unsafe-inline' を追加すると、 CSP の XSS 防御効果がほぼ無効化される。 nonce 方式への移行が正解。
script-src に * を指定すると任意のドメインからスクリプトを読み込めてしまう。許可するドメインは個別に列挙する。
広告、アナリティクス、チャットウィジェットなどのサードパーティスクリプトを忘れると、本番で機能が停止する。
CSP はWAF やSSL/TLS と並ぶ Web セキュリティの基盤技術です。web security books on Amazonで体系的に学ぶことを推奨します。ブラウザ拡張機能のセキュリティやブラウザパスワードの安全性、スタートアップのセキュリティチェックリストも あわせて参照してください。
Was this article helpful?