ホーム/ヘッダー/Content-Security-PolicyContent-Security-Policy使い方 Content-Security-Policy(CSP)ヘッダーは、リソースの読み込みに対するきめ細かな制御をサイト管理者に与えます。ポリシーを宣言することで、サーバーは承認されたソースからのみスクリプト、スタイル、画像、フォントなどのリソースを読み込むようブラウザに指示します。ポリシーに一致しないリソースはブロックされ、ブラウザが違反を報告します。 ポリシーは、セミコロンで区切られた 1 つ以上のディレクティブで構成されます。各ディレクティブはリソースの種類を指定し、その種類に許可されるソースを列挙します。 Content-Security-Policy: <directive> <source>; <directive> <source> 新しいポリシーをまずレポート専用モードで導入するのは一般的な手法です。Content-Security-Policy-Report-Only ヘッダーは同じ構文を使いますが、リソースをブロックせずに違反を記録するため、管理者は強制する前にポリシーをテストできます。 Fetch ディレクティブ Fetch ディレクティブは、特定の種類のリソースがどこから読み込まれるかを制御します。 default-src default-src ディレクティブは、他のすべての fetch ディレクティブのフォールバックとして機能します。特定の fetch ディレクティブがない場合、ブラウザは default-src にフォールバックします。 Content-Security-Policy: default-src 'self' script-src script-src ディレクティブは、JavaScript の実行に対するソースを制限します。nonce ベースおよびハッシュベースの許可リストは、ホストベースの規則より強力な保護を提供します。 script-src-elem script-src-elem ディレクティブは script-src-attr script-src-attr ディレクティブは、 style-src style-src ディレクティブは、インラインのスタイルや外部スタイルシートのリンクを含め、CSS スタイルシートの有効なソースを指定します。 style-src-elem style-src-elem ディレクティブは style-src-attr style-src-attr ディレクティブは、style 属性を通じて DOM 要素に直接適用されるインラインのスタイルを統制します。 img-src img-src ディレクティブは、画像とファビコンの有効なソースを指定します。 connect-src connect-src ディレクティブは、fetch()、XMLHttpRequest、WebSocket、EventSource を含むスクリプトのインターフェースからアクセスできる URL を制限します。 font-src font-src ディレクティブは、@font-face を通じて読み込まれるフォントの有効なソースを指定します。 frame-src frame-src ディレクティブは、 要素と 要素によって読み込まれる入れ子のブラウジングコンテキストの有効なソースを指定します。 media-src media-src ディレクティブは、、、 の各要素の有効なソースを指定します。 object-src object-src ディレクティブは、 要素と 要素のソースを制限します( は HTML 仕様から削除されたレガシー要素です)。これらの要素が必要になることはまれなので、‘none’ に設定することが推奨されます。 child-src child-src ディレクティブは、Web Worker と入れ子のブラウジングコンテキストに許可されるソースを定義します。より具体的な frame-src と worker-src のディレクティブが存在する場合は、それらが child-src を上書きします。 worker-src worker-src ディレクティブは、Worker、SharedWorker、ServiceWorker のスクリプトに適用されます。 manifest-src manifest-src ディレクティブは、Web アプリケーションのマニフェストファイルの有効なソースを指定します。 fenced-frame-src fenced-frame-src ディレクティブは、 要素に読み込まれる入れ子のブラウジングコンテキストの有効なソースを指定します。これがない場合、ブラウザは frame-src へ、次いで default-src へフォールバックします。 Document ディレクティブ Document ディレクティブは、文書の環境に関する性質を統制します。 base-uri base-uri ディレクティブは 要素で許可される URL を制限し、攻撃者が相対リンクの基準 URL を変更するのを防ぎます。 sandbox sandbox ディレクティブは、 の sandbox 属性に似た制約をページに適用します。サンドボックス化されたページは、sandbox のフラグで明示的に再度有効化しない限り、スクリプト、フォーム、ポップアップなどの機能へのアクセスを失います。 Navigation ディレクティブ Navigation ディレクティブは、ユーザーとフォームがどこへリクエストを送るかを制御します。 form-action form-action ディレクティブは、フォームの送信先として受け入れる URL を制限します。 frame-ancestors frame-ancestors ディレクティブは、、、<object>、<embed> を使ってページを埋め込むことが許される親を指定します(<applet> 要素は HTML 仕様から削除されています)。frame-ancestors ‘none’ の設定は X-Frame-Options: DENY ヘッダーの代わりになります。 navigate-to navigate-to ディレクティブは、あらゆる手段を通じて文書が遷移できる URL を制限するものとして提案されました。このディレクティブは CSP Level 3 の仕様から削除され、どの製品版ブラウザにも実装されませんでした。 Reporting ディレクティブ Reporting ディレクティブは、違反の報告に関する挙動を制御します。 report-to report-to ディレクティブは、Reporting-Endpoints ヘッダーで定義されたレポートのグループ名を指定します。違反のレポートは、指定されたグループに紐づくエンドポイントへ送られます。 report-uri report-uri ディレクティブは、指定した URL へ違反のレポートを送ります。このディレクティブは report-to に置き換えられつつありますが、後方互換性のために今も広く使われています。 upgrade-insecure-requests upgrade-insecure-requests ディレクティブは、ページ上のすべての HTTP の URL を HTTPS として扱うようブラウザに指示します。これは、多くのリソースが依然として安全でない URL を参照している、HTTP から HTTPS への移行期に有用です。 require-trusted-types-for require-trusted-types-for ディレクティブは、DOM XSS のインジェクションシンクに対して Trusted Types のポリシーを強制し、文字列ではなく型付きオブジェクトを要求します。 trusted-types trusted-types ディレクティブは Trusted Types のポリシー名の許可リストを指定し、そのページが作成できるポリシーを制限します。 ソース値 ディレクティブは、リソースの読み込み元を定義するソース式を受け付けます。 ‘self’ 現在のオリジン(同じスキーム、ホスト、ポート)に一致します。サブドメインは含みません。 ‘none’ そのディレクティブのすべてのソースをブロックします。指定された種類のリソースは一切読み込まれません。 ‘unsafe-inline’ インラインの ‘unsafe-eval’ eval()、Function() などの構文を通じた動的なコード評価を許可します。 ‘unsafe-hashes’ すべてのインラインスクリプトを有効にすることなく、ハッシュで識別される特定のインラインのイベントハンドラーを許可します。 ‘strict-dynamic’ すでに信頼されたスクリプトが読み込むスクリプトへ信頼を拡張します。nonce ベースのポリシーと組み合わせることで、スクリプトのホストを個別に許可リストへ加える必要がなくなります。 ‘nonce-*’ サーバーがレスポンスごとに生成する暗号的な nonce(一度だけ使われる数)です。ポリシー中の nonce の値は、 Content-Security-Policy: script-src 'nonce-abc123' ‘sha256-’、‘sha384-’、‘sha512-*’ インラインのスクリプトやスタイルの内容のハッシュです。ブラウザは各インラインブロックのハッシュを計算し、その結果を許可リストのハッシュと照合します。 host-source 許可するオリジンを指定するホストまたは URL のパターンです。サブドメインのワイルドカード(*.example.re)、特定のポート(example.re:443)、パスの接頭辞(example.re/scripts/)をサポートします。 scheme-source https: や data: のようなスキームで、指定したプロトコルで配信されるすべてのリソースを許可します。 ‘report-sample’ script-src や style-src の値に加える ‘report-sample’ キーワードは、違反のレポートに違反したコードの短いサンプルを含めるようブラウザに要求します。これは、問題のあるインラインのスクリプトやスタイルを特定するのに役立ちます。 例 同一オリジンからのリソースのみを許可する制限的なポリシーは、すべてのインラインスクリプトと外部リソースの読み込みをブロックします。 Content-Security-Policy: default-src 'self' スクリプトと画像に別々の規則を設けたポリシーです。スクリプトは同一オリジンからのみ読み込まれ、画像は専用の画像 CDN からも読み込まれます。 Content-Security-Policy: default-src 'self'; img-src 'self' images.example.re スクリプトに対する nonce ベースのポリシーです。ページの読み込みごとに新しい nonce が生成され、一致する nonce 属性を持つ Content-Security-Policy: script-src 'nonce-r4nd0m'; style-src 'self' ‘strict-dynamic’ と nonce を組み合わせたポリシーです。信頼されたスクリプトは、ホストごとの個別の許可リストなしに追加のスクリプトを自由に読み込めます。 Content-Security-Policy: script-src 'strict-dynamic' 'nonce-r4nd0m' 規則を強制しつつ、監視のために違反をエンドポイントへ報告するポリシーです。 Content-Security-Policy: default-src 'self'; report-to csp-violations トラブルシューティング CSP の違反は、ブロックされたリソースの URI と、ブロックの原因となったディレクティブを伴う「Refused to…」のメッセージとしてブラウザのコンソールに現れます。 CSP を追加した後にインラインスクリプトがブロックされる。ブラウザは Refused to execute inline script because it violates the following Content Security Policy directive: “script-src …” というログを出します。既定のポリシーはすべてのインラインの インラインスタイルがブロックされる。style-src が ‘unsafe-inline’ や一致する nonce/ハッシュを含まない場合、コンソールに Refused to apply inline style と表示されます。実行時にスタイルを注入するフレームワークはこの違反を引き起こします。style-src に nonce を加えるか、nonce ベースのスタイルへ移行する間は ‘unsafe-inline’ を使ってください。 ディレクティブにドメインがないために外部リソースがブロックされる。Refused to load the script や Refused to connect のエラーは、そのリソースのオリジンが該当するディレクティブに列挙されていないことを意味します。ブラウザのコンソールを開き、違反のメッセージからブロックされたオリジンを特定し、正しいディレクティブ(script-src、img-src、connect-src など)にそのオリジンを加えてください。ディレクティブがない場合は既定にフォールバックするため、default-src も確認します。 eval() が既定でブロックされる。eval()、new Function()、テンプレートコンパイラーに依存するライブラリは Refused to evaluate a string as JavaScript を引き起こします。script-src に ‘unsafe-eval’ を加えるとその機能は戻りますが、ポリシーは弱くなります。可能な限り、eval() を避けるようコードをリファクタリングすることが望ましいです。 CSP のもとで Google Tag Manager やアクセス解析のスクリプトが壊れる。タグマネージャーはスクリプトを動的に注入するため、注入される各スクリプトには nonce かホストの許可リストのエントリが必要です。GTM のドメイン(https://www.googletagmanager.com)を script-src に、https://www.google-analytics.com を connect-src と img-src に加えてください。nonce ベースのポリシーでは ‘strict-dynamic’ を使い、信頼された GTM のスクリプトが読み込むスクリプトが、ホストごとのエントリなしに信頼を引き継ぐようにします。 ブラウザのコンソールで違反をデバッグする。DevTools を開き、Console タブで CSP の違反メッセージを確認してください。各メッセージには、ブロックされた URI、違反したディレクティブ、ポリシー全文が示されます。Chrome では Network タブがブロックされたリクエストに (blocked:csp) のステータスを付けます。Firefox も Console と Network の両方のパネルで同様の詳細を提供します。 Report-Only モードでポリシーを安全にテストする。まず Content-Security-Policy-Report-Only ヘッダーを使ってポリシーを配信してください。これはリソースを一切ブロックせずに違反を記録します。違反のレポートを監視し、不足しているソースを修正し、レポートが途絶えたら強制的な Content-Security-Policy ヘッダーへ切り替えます。