Overview
CSP(Content Security Policy)とは、Webページが読み込むことができるコンテンツのソース(スクリプト、スタイルシート、画像、フォントなど)をHTTPレスポンスヘッダーで宣言的に制限するセキュリティ機能です。クロスサイトスクリプティング(XSS)攻撃の防御において最も効果的な対策の一つとされています。
CSPはW3Cにより標準化されており、現在の主要なバージョンはCSP Level 3です。Content-Security-PolicyヘッダーをHTTPレスポンスに含めることで、ブラウザに対して許可するコンテンツソースのホワイトリスト(許可リスト)を伝達します。ポリシーに違反するコンテンツの読み込みをブラウザが自動的にブロックします。
CSPの導入により、仮にXSS脆弱性が存在していても、攻撃者が注入したスクリプトの実行をブラウザレベルで阻止できます。また、データの外部送信やインラインスクリプトの実行を制限することで、データ漏洩の防止にも効果を発揮します。ただし、CSPは防御層の一つであり、根本的な脆弱性修正(入力バリデーション・出力エンコーディング)の代替にはなりません。
Details
主要なCSPディレクティブ
- default-src:他のディレクティブで明示的に指定されていないリソースのデフォルトソース。すべてのCSPポリシーの基盤となるフォールバック設定
- script-src:JavaScriptの読み込み元を制限。XSS対策の核心。'self'(同一オリジン)、特定のドメイン、'nonce-{値}'、'sha256-{ハッシュ}'などを指定可能
- style-src:CSSスタイルシートの読み込み元を制限。インラインスタイルの制御にも使用
- img-src:画像の読み込み元を制限。データURIスキーム(data:)の許可もここで制御
- connect-src:XMLHttpRequest、Fetch API、WebSocketなどの接続先を制限。データの外部送信防止に重要
- font-src:Webフォントの読み込み元を制限
- frame-src:iframe等のフレーム内に埋め込めるコンテンツのソースを制限
- frame-ancestors:自ページをiframeに埋め込める親ページのソースを制限。クリックジャッキング対策として有効
- form-action:フォームの送信先URLを制限
- base-uri:base要素で指定できるURLを制限。base要素の悪用による相対URLのハイジャック防止
nonceとhashによるインラインスクリプト制御
CSPでは原則としてインラインスクリプト(<script>タグ内の直接記述やイベントハンドラ)の実行が禁止されます。正当なインラインスクリプトを許可するために2つのアプローチがあります。
- nonce方式:サーバーがリクエストごとにランダムな一意の値(nonce)を生成し、CSPヘッダーとscriptタグの両方に含めます。一致するnonceを持つスクリプトのみ実行が許可されます。例:Content-Security-Policy: script-src 'nonce-abc123' とし、<script nonce="abc123">で記述
- hash方式:許可するスクリプトのSHA-256/SHA-384/SHA-512ハッシュ値をCSPヘッダーに記載します。スクリプトの内容が完全に一致する場合のみ実行が許可されます。静的なインラインスクリプトに適しています
strict-dynamicとCSPの進化
'strict-dynamic'はCSP Level 3で導入された機能で、信頼されたスクリプト(nonceまたはhashで許可されたスクリプト)が動的に読み込む追加のスクリプトにも信頼を伝播させます。これにより、サードパーティスクリプトが内部的に読み込むスクリプトチェーンにも対応でき、複雑なWebアプリケーションでのCSP導入が容易になりました。
Googleが提唱するStrict CSPは、ホワイトリストベースのCSPの限界を踏まえ、nonceベース + strict-dynamic を中心としたCSPポリシーを推奨するアプローチです。ホワイトリストのドメインにCDNやJSONPエンドポイントが含まれる場合、CSPバイパスが容易になるという問題を解決します。
report-uri / report-toによる違反レポート
CSPには、ポリシー違反を検知した際にレポートを送信する機能があります。report-uri(CSP Level 2)またはreport-to(CSP Level 3、Reporting API対応)ディレクティブで指定したエンドポイントにJSON形式の違反レポートが送信されます。
Content-Security-Policy-Report-Onlyヘッダーを使用すると、ポリシーを強制せずに違反レポートのみ収集できます。これはCSP導入前のテストフェーズで非常に有用で、既存のWebアプリケーションへのCSP適用による影響を事前に把握できます。
CSP Level 3の主要な新機能
- 'strict-dynamic':信頼チェーンによるスクリプトの動的読み込み許可
- 'unsafe-hashes':イベントハンドラ属性(onclick等)のハッシュベースでの個別許可
- script-src-elem / script-src-attr:script要素とイベントハンドラ属性を個別に制御
- style-src-elem / style-src-attr:style要素とstyle属性を個別に制御
- Reporting APIとの統合:report-toディレクティブによる標準的なレポーティングフレームワークとの連携
Security Measures
- 01Report-Onlyモードでの段階的導入:CSPをいきなり強制モードで導入すると、正当なスクリプトがブロックされてサイトが壊れるリスクがあります。まずContent-Security-Policy-Report-Onlyヘッダーで違反レポートを収集し、ポリシーを調整してから強制モードに移行してください。
- 02nonceベースのStrict CSPを採用:ドメインベースのホワイトリストCSPはバイパスされるリスクが高いため、Googleが推奨するnonce + strict-dynamicベースのStrict CSPを採用してください。リクエストごとに暗号学的に安全なランダムnonceを生成しましょう。
- 03'unsafe-inline'と'unsafe-eval'の排除:'unsafe-inline'はインラインスクリプトを全面許可するため、XSS対策としてのCSPの効果を大幅に低下させます。'unsafe-eval'もeval()やsetTimeout(string)の実行を許可するため、可能な限り使用を避けてください。
- 04違反レポートの監視と分析:report-toディレクティブを設定し、CSP違反レポートを継続的に監視してください。正当な違反(ポリシーの調整が必要)と攻撃の兆候を区別し、適切な対応を行いましょう。Report URIやSentryなどのサービスの活用も有効です。
- 05frame-ancestorsによるクリックジャッキング防止:frame-ancestors 'none'または frame-ancestors 'self'を設定して、自サイトのページが外部サイトのiframe内に埋め込まれることを防止してください。X-Frame-Optionsヘッダーの代替として、より柔軟な制御が可能です。
- 06定期的なCSPポリシーの見直しとテスト:Google CSP EvaluatorやCSP Scanner等のツールを使用して、CSPポリシーの強度を定期的に評価してください。新しいサードパーティスクリプトの追加やサイト変更時にはポリシーの更新を忘れずに行いましょう。
Incidents
📋 GitHub CSP導入事例 — 大規模サービスでのCSP実装
GitHubは、世界最大級のソフトウェア開発プラットフォームとして、早期からCSPの導入に取り組んできました。ユーザー生成コンテンツを大量に扱うサービスであるため、XSS攻撃のリスクが高く、CSPは防御の重要な柱となっています。
GitHubはnonceベースのCSPを採用し、インラインスクリプトの実行を厳密に制御しています。導入過程では、レガシーコードのインラインスクリプト依存の解消、サードパーティ統合の対応、パフォーマンスへの影響評価など、多くの技術的課題を段階的に解決しました。CSP違反レポートの分析により、実際の攻撃試行を検出した事例も報告されており、CSPが防御だけでなく検知にも有効であることを実証しています。
📋 Google CSP Evaluator — CSPポリシー評価ツールの提供
Googleのセキュリティチームは、世界中のWebサイトが設定しているCSPポリシーを大規模に分析し、多くのCSPがバイパス可能であるという研究結果を公表しました。特に、ドメインベースのホワイトリストCSPでは、CDN上のJSONPエンドポイントやAngularJSライブラリを悪用したバイパスが広く可能であることが判明しました。
この研究を踏まえ、GoogleはCSP Evaluatorツールを公開し、CSPポリシーの安全性を自動評価できるようにしました。また、nonce + strict-dynamicベースのStrict CSPを提唱し、より堅牢なCSP設計のベストプラクティスを業界に広めました。この取り組みにより、CSPの運用方法が大きく変化し、多くの組織がStrict CSPへの移行を進めています。
📋 CSPバイパス手法の研究と対策の進化
セキュリティ研究コミュニティでは、CSPバイパス手法の研究が活発に行われています。代表的なバイパス手法として、JSONP callback、AngularJSのsandbox escape、script gadget(ホワイトリストされたライブラリ内の悪用可能な機能)、base-uri未設定による相対URLハイジャック、CSPが未適用のフレーム内での攻撃実行などが知られています。
これらの研究により、CSPの仕様や実装が継続的に改善されています。CSP Level 3でのstrict-dynamicの導入、script-src-elemとscript-src-attrの分離、Trusted Types APIとの連携など、攻撃者とのいたちごっこの中でCSPのセキュリティモデルは進化を続けています。CSPは単独で完璧な防御を提供するものではなく、入力バリデーション、出力エンコーディング、Trusted Typesと組み合わせた多層防御が推奨されます。