Tests
- DOMParser-parseFromString-regression.html (live test) (source)
- DOMParser-parseFromString.html (live test) (source)
- DedicatedWorker-block-eval-function-constructor.html (live test) (source)
- DedicatedWorker-constructor-from-DedicatedWorker.html (live test) (source)
- DedicatedWorker-constructor-from-SharedWorker.html (live test) (source)
- DedicatedWorker-constructor.https.html (live test) (source)
- DedicatedWorker-eval.html (live test) (source)
- DedicatedWorker-importScripts.html (live test) (source)
- DedicatedWorker-setTimeout-setInterval.html (live test) (source)
- Document-execCommand.html (live test) (source)
- Document-write-appending-line-feed.html (live test) (source)
- Document-write-exception-order.xhtml (live test) (source)
- Document-write.html (live test) (source)
- Element-insertAdjacentHTML.html (live test) (source)
- Element-outerHTML.html (live test) (source)
- Element-setAttribute-respects-Elements-node-documents-globals-CSP-after-adoption-from-TT-realm.html (live test) (source)
- Element-setAttribute-respects-Elements-node-documents-globals-CSP-after-adoption-from-non-TT-realm.html (live test) (source)
- Element-setAttribute.html (live test) (source)
- Element-setAttributeNS.html (live test) (source)
- Element-toggleAttribute.html (live test) (source)
- GlobalEventHandlers-onclick.html (live test) (source)
- HTMLElement-generic.html (live test) (source)
- HTMLScriptElement-in-xhtml-document.tentative.https.xhtml (live test) (source)
- HTMLScriptElement-internal-slot.html (live test) (source)
- Node-multiple-arguments-tt-enforced.html (live test) (source)
- Node-multiple-arguments.html (live test) (source)
- Range-createContextualFragment.html (live test) (source)
- SVGScriptElement-internal-slot.html (live test) (source)
- ServiceWorker-block-eval-function-constructor.https.html (live test) (source)
- ServiceWorker-eval.https.html (live test) (source)
- ServiceWorker-importScripts.https.html (live test) (source)
- ServiceWorkerContainer-register-from-DedicatedWorker.https.html (live test) (source)
- ServiceWorkerContainer-register-from-ServiceWorker.https.html (live test) (source)
- ServiceWorkerContainer-register-from-SharedWorker.https.html (live test) (source)
- ServiceWorkerContainer-register.https.html (live test) (source)
- SharedWorker-block-eval-function-constructor.html (live test) (source)
- SharedWorker-constructor.https.html (live test) (source)
- SharedWorker-eval.html (live test) (source)
- SharedWorker-importScripts.html (live test) (source)
- SharedWorker-setTimeout-setInterval.html (live test) (source)
- TrustedType-AttributeNodes.html (live test) (source)
- TrustedTypePolicy-CSP-no-name.html (live test) (source)
- TrustedTypePolicy-CSP-wildcard.html (live test) (source)
- TrustedTypePolicy-createXXX.html (live test) (source)
- TrustedTypePolicyFactory-constants.html (live test) (source)
- TrustedTypePolicyFactory-createPolicy-createXYZTests.html (live test) (source)
- TrustedTypePolicyFactory-createPolicy-cspTests-noNamesGiven.html (live test) (source)
- TrustedTypePolicyFactory-createPolicy-cspTests-none-none-name.html (live test) (source)
- TrustedTypePolicyFactory-createPolicy-cspTests-none-none.html (live test) (source)
- TrustedTypePolicyFactory-createPolicy-cspTests-none-skip.html (live test) (source)
- TrustedTypePolicyFactory-createPolicy-cspTests-none.html (live test) (source)
- TrustedTypePolicyFactory-createPolicy-cspTests-wildcard.html (live test) (source)
- TrustedTypePolicyFactory-createPolicy-cspTests.html (live test) (source)
- TrustedTypePolicyFactory-createPolicy-non-tt-policy-name.html (live test) (source)
- TrustedTypePolicyFactory-createPolicy-unenforced.html (live test) (source)
- TrustedTypePolicyFactory-defaultPolicy.html (live test) (source)
- TrustedTypePolicyFactory-getAttributeType-namespace.html (live test) (source)
- TrustedTypePolicyFactory-getAttributeType-svg.html (live test) (source)
- TrustedTypePolicyFactory-getAttributeType.html (live test) (source)
- TrustedTypePolicyFactory-isXXX.html (live test) (source)
- Window-TrustedTypes.html (live test) (source)
- Window-block-eval-function-constructor.html (live test) (source)
- Window-setTimeout-setInterval.html (live test) (source)
- block-Document-execCommand.html (live test) (source)
- block-string-assignment-to-DOMParser-parseFromString.html (live test) (source)
- block-string-assignment-to-DedicatedWorker-setTimeout-setInterval.html (live test) (source)
- block-string-assignment-to-Document-parseHTMLUnsafe.html (live test) (source)
- block-string-assignment-to-Document-write.html (live test) (source)
- block-string-assignment-to-Element-insertAdjacentHTML.html (live test) (source)
- block-string-assignment-to-Element-outerHTML.html (live test) (source)
- block-string-assignment-to-Element-setAttribute.html (live test) (source)
- block-string-assignment-to-Element-setAttributeNS.html (live test) (source)
- block-string-assignment-to-Element-setHTMLUnsafe.html (live test) (source)
- block-string-assignment-to-HTMLElement-generic.html (live test) (source)
- block-string-assignment-to-HTMLIFrameElement-srcdoc.html (live test) (source)
- block-string-assignment-to-Range-createContextualFragment.html (live test) (source)
- block-string-assignment-to-ShadowRoot-innerHTML.html (live test) (source)
- block-string-assignment-to-ShadowRoot-setHTMLUnsafe.html (live test) (source)
- block-string-assignment-to-SharedWorker-setTimeout-setInterval.html (live test) (source)
- block-string-assignment-to-Window-setTimeout-setInterval.html (live test) (source)
- block-string-assignment-to-attribute-via-attribute-node.html (live test) (source)
- block-string-assignment-to-text-and-url-sinks.html (live test) (source)
- block-text-node-insertion-into-script-element.html (live test) (source)
- block-text-node-insertion-into-svg-script-element.html (live test) (source)
- csp-block-eval.html (live test) (source)
- default-policy-callback-arguments.html (live test) (source)
- default-policy-report-only.html (live test) (source)
- default-policy.html (live test) (source)
- empty-default-policy-report-only.html (live test) (source)
- empty-default-policy.html (live test) (source)
- eval-csp-no-tt.html (live test) (source)
- eval-csp-tt-default-policy-mutate.html (live test) (source)
- eval-csp-tt-default-policy.html (live test) (source)
- eval-csp-tt-no-default-policy.html (live test) (source)
- eval-function-constructor-untrusted-arguments-and-applying-default-policy.html (live test) (source)
- eval-function-constructor-untrusted-arguments-and-default-policy-throwing.html (live test) (source)
- eval-function-constructor.html (live test) (source)
- eval-no-csp-no-tt-default-policy.html (live test) (source)
- eval-no-csp-no-tt.html (live test) (source)
- eval-with-permissive-csp.html (live test) (source)
- get-trusted-types-compliant-attribute-value.html (live test) (source)
- idlharness.window.js (live test) (source)
- inheriting-csp-for-local-schemes.html (live test) (source)
- legacy-trusted-script-urls.html (live test) (source)
- legacy-trusted-scripts.html (live test) (source)
- modify-attributes-in-callback.html (live test) (source)
- no-require-trusted-types-for-report-only.html (live test) (source)
- no-require-trusted-types-for.html (live test) (source)
- require-trusted-types-for-TypeError-belongs-to-the-global-object-realm.html (live test) (source)
- require-trusted-types-for-report-only.html (live test) (source)
- require-trusted-types-for.html (live test) (source)
- script-enforcement-001-outerHTML.xhtml (live test) (source)
- script-enforcement-001.html (live test) (source)
- script-enforcement-002-outerHTML.xhtml (live test) (source)
- script-enforcement-002.html (live test) (source)
- script-enforcement-003.html (live test) (source)
- script-enforcement-004.html (live test) (source)
- script-enforcement-005.html (live test) (source)
- script-enforcement-006.html (live test) (source)
- script-enforcement-007.html (live test) (source)
- script-enforcement-008.https.html (live test) (source)
- script-enforcement-009.https.html (live test) (source)
- script-enforcement-010.html (live test) (source)
- script-enforcement-011.html (live test) (source)
- set-attributes-no-require-trusted-types.html (live test) (source)
- set-attributes-require-trusted-types-default-policy.html (live test) (source)
- set-attributes-require-trusted-types-no-default-policy.html (live test) (source)
- should-sink-type-mismatch-violation-be-blocked-by-csp-001.html (live test) (source)
- should-sink-type-mismatch-violation-be-blocked-by-csp-002-worker.html (live test) (source)
- should-sink-type-mismatch-violation-be-blocked-by-csp-003.html (live test) (source)
- should-trusted-type-policy-creation-be-blocked-by-csp-001.html (live test) (source)
- should-trusted-type-policy-creation-be-blocked-by-csp-002.html (live test) (source)
- should-trusted-type-policy-creation-be-blocked-by-csp-003.html (live test) (source)
- should-trusted-type-policy-creation-be-blocked-by-csp-004-worker.html (live test) (source)
- should-trusted-type-policy-creation-be-blocked-by-csp-005.html (live test) (source)
- trusted-types-createHTMLDocument.html (live test) (source)
- trusted-types-duplicate-names-list-report-only.html (live test) (source)
- trusted-types-duplicate-names-list.html (live test) (source)
- trusted-types-duplicate-names-without-enforcement.html (live test) (source)
- trusted-types-duplicate-names.html (live test) (source)
- trusted-types-eval-reporting-no-unsafe-eval.html (live test) (source)
- trusted-types-eval-reporting-report-only.html (live test) (source)
- trusted-types-event-handlers.html (live test) (source)
- trusted-types-navigation.html (live test) (source)
- trusted-types-report-only.html (live test) (source)
- trusted-types-reporting-check-report-DedicatedWorker-create-policy.html (live test) (source)
- trusted-types-reporting-check-report-DedicatedWorker-sink-mismatch.html (live test) (source)
- trusted-types-reporting-check-report-Window-create-policy.html (live test) (source)
- trusted-types-reporting-check-report-Window-sink-mismatch.html (live test) (source)
- trusted-types-reporting-clipping-of-sample.html (live test) (source)
- trusted-types-reporting-for-DOMParser-parseFromString.html (live test) (source)
- trusted-types-reporting-for-DedicatedWorker-DedicatedWorker-constructor.html (live test) (source)
- trusted-types-reporting-for-DedicatedWorker-ServiceWorkerContainer-register.https.html (live test) (source)
- trusted-types-reporting-for-DedicatedWorker-eval.html (live test) (source)
- trusted-types-reporting-for-DedicatedWorker-function-constructor.html (live test) (source)
- trusted-types-reporting-for-DedicatedWorker-importScripts.html (live test) (source)
- trusted-types-reporting-for-DedicatedWorker-setTimeout-setInterval.html (live test) (source)
- trusted-types-reporting-for-Document-execCommand.html (live test) (source)
- trusted-types-reporting-for-Document-parseHTMLUnsafe.html (live test) (source)
- trusted-types-reporting-for-Document-write.html (live test) (source)
- trusted-types-reporting-for-Element-innerHTML.html (live test) (source)
- trusted-types-reporting-for-Element-insertAdjacentHTML.html (live test) (source)
- trusted-types-reporting-for-Element-outerHTML.html (live test) (source)
- trusted-types-reporting-for-Element-setAttribute.html (live test) (source)
- trusted-types-reporting-for-Element-setHTMLUnsafe.html (live test) (source)
- trusted-types-reporting-for-HTMLIFrameElement-srcdoc.html (live test) (source)
- trusted-types-reporting-for-HTMLScriptElement-children-change.html (live test) (source)
- trusted-types-reporting-for-HTMLScriptElement-innerHTML.html (live test) (source)
- trusted-types-reporting-for-HTMLScriptElement.html (live test) (source)
- trusted-types-reporting-for-Range-createContextualFragment.html (live test) (source)
- trusted-types-reporting-for-SVGScriptElement-children-change.html (live test) (source)
- trusted-types-reporting-for-SVGScriptElement-innerHTML.html (live test) (source)
- trusted-types-reporting-for-ServiceWorker-ServiceWorkerContainer-register.https.html (live test) (source)
- trusted-types-reporting-for-ServiceWorker-eval.https.html (live test) (source)
- trusted-types-reporting-for-ServiceWorker-function-constructor.https.html (live test) (source)
- trusted-types-reporting-for-ServiceWorker-importScripts.https.html (live test) (source)
- trusted-types-reporting-for-ServiceWorker-setTimeout-setInterval.https.html (live test) (source)
- trusted-types-reporting-for-ShadowRoot-innerHTML.html (live test) (source)
- trusted-types-reporting-for-ShadowRoot-setHTMLUnsafe.html (live test) (source)
- trusted-types-reporting-for-SharedWorker-DedicatedWorker-constructor.html (live test) (source)
- trusted-types-reporting-for-SharedWorker-ServiceWorkerContainer-register.https.html (live test) (source)
- trusted-types-reporting-for-SharedWorker-eval.html (live test) (source)
- trusted-types-reporting-for-SharedWorker-function-constructor.html (live test) (source)
- trusted-types-reporting-for-SharedWorker-importScripts.html (live test) (source)
- trusted-types-reporting-for-SharedWorker-setTimeout-setInterval.html (live test) (source)
- trusted-types-reporting-for-Window-DedicatedWorker-constructor.html (live test) (source)
- trusted-types-reporting-for-Window-ServiceWorkerContainer-register.https.html (live test) (source)
- trusted-types-reporting-for-Window-SharedWorker-constructor.html (live test) (source)
- trusted-types-reporting-for-Window-eval.html (live test) (source)
- trusted-types-reporting-for-Window-function-constructor.html (live test) (source)
- trusted-types-reporting-for-Window-setTimeout-setInterval.html (live test) (source)
- trusted-types-reporting.html (live test) (source)
- trusted-types-sandbox-allow-scripts.html (live test) (source)
- trusted-types-sandbox-no-allow-scripts.html (live test) (source)
- trusted-types-source-file-path.html (live test) (source)
- trusted-types-svg-script-set-href.html (live test) (source)
- trusted-types-tojson.html (live test) (source)
- tt-block-eval.html (live test) (source)
1. はじめに
この節は規範的ではない。
特定の種類の脆弱性は、Web アプリケーションが 攻撃者が制御するソース(例えば 文書 URL のパラメーターや postMessage チャネル)から値を取得し、その値を、 適切にサニタイズせずに インジェクションシンク、すなわち強力な機能を備えたさまざまな Web API 関数へ 渡す場合に発生する。
この種の問題は、従来から防止することが困難である。
アプリケーションは一般に、作者が気付かないまま、攻撃者が制御する
値をそれらのインジェクションシンクに渡して呼び出す。これは、
インジェクションシンクを呼び出す時点では入力が攻撃者に制御されていたかが明確でないためである。
JavaScript の動的な性質により、このようなパターンが
特定のプログラムに存在しないことを確認することも困難である。この問題はしばしば
手動コードレビューや自動コード解析で見落とされる。例えば、
aString に信頼できないデータが含まれる場合、foo[bar] = aString は、
foo と bar の値によっては
脆弱性を引き起こす可能性がある文である。
この文書は、攻撃者が制御するデータが
§ 2.1.1 DOM XSS インジェクションシンク に到達した際に発生する DOM ベースのクロスサイトスクリプティングの防止に
焦点を当てる。これは最終的に、
攻撃者が制御するスクリプトペイロードの実行を引き起こす。DOM XSS は
60 種類を超える異なる
インジェクションシンク(例えば Element.innerHTML や Location.href のセッター)が存在するため、Web
アプリケーションで広く見られる。
この文書では Trusted Types、すなわちアプリケーションが インジェクションシンクをロックダウンし、 文字列の代わりに偽装不可能な型付き値のみを 受け入れるようにできる API を定義する。これらの値は、アプリケーションが定義した ポリシーからのみ 作成できるため、作者は 危険な API を保護する規則を定義でき、攻撃面を Web アプリケーションのコードベースの 小さく分離された部分へと縮小できる。その部分は、 保護、監視、レビューが大幅に容易になる。
1.1. 目標
-
信頼できないデータを使用して強力な Web API を 呼び出す際に発生するクライアント側の脆弱性の可能性を最小限にする。例えば、 DOM XSS の可能性を最小限にする。
-
セキュリティ上の判断を アプリケーションの小さな部分にカプセル化する設計を促進する。
-
複雑な Web アプリケーションのコードベースに対する セキュリティレビューの対象範囲を縮小する。
-
通常のプログラミングエラーが検出され開発者に提示されるのと同様に、 ユーザビリティを維持しながら脆弱性を検出できるようにし、 動的および静的解析ツールによる支援を可能にする。
1.2. 非目標
-
サーバー側で生成されたマークアップへのインジェクション、特に 文書内で実行されるスクリプト本体への反映を防止、またはその結果を 緩和すること。サーバー側の XSS ベクトルに対処するには、既存の テンプレートシステムや CSP script-src のような解決策を推奨する。
-
例えばデータ流出の防止や、 [Fetch]を介した外部ソースへの接続を防ぐための、リソースの制約に対処すること。
-
サブリソースの読み込みを制御すること。Trusted Types は、作者が 現在の文書をスクリプト実行可能にするリソースの読み込みを 制御できるようにすることを目的とするが、その他のサブリソースは対象としない。
-
クロスオリジンの JavaScript 実行を防止すること(例えば、Trusted Types は
data:URL を介して JavaScript コードを含む新しい文書を読み込むことを防がない)。 -
Web アプリケーションの JavaScript コードの悪意ある作者が 制限を回避できないようにすること。悪意ある作者から保護しようとすると、 過度に複雑で実用的でない 設計になる。
1.3. ユースケース
-
作者が、安全なテンプレートシステムを使用して UI コンポーネントを生成するフレームワークで記述された複雑な Web アプリケーションを 保守している。このアプリケーションは、補助的なタスク(例えば解析やパフォーマンス 監視)を実行するサードパーティのクライアント側 ライブラリにも依存している。これらのコンポーネントが DOM XSS 脆弱性を導入しないことを保証するため、作者は テンプレートライブラリ内に Trusted Type ポリシーを定義し、§ 2.1.1 DOM XSS インジェクションシンクに対する強制を有効にする。
-
Web サイトが § 2.1.1 DOM XSS インジェクションシンクを使用している。 Web サイト開発者はそこに Trusted Types を導入し、 Content-Security-Policy-Report-Only ヘッダーフィールドを使用して違反を監視する。 コードを安全な メソッドのみを使用するようリファクタリングすることで、違反を反復的に修正する。その後、§ 2.1.1 DOM XSS インジェクションシンクは 一切呼び出されなくなる。 したがって、Trusted Types も不要になる。開発者は report-only モードを無効にし、 trusted-types および require-trusted-types-for ディレクティブによって Trusted Type ポリシーを無効にする。 リファクタリング中も Web サイトの機能が損なわれることはなかった。
-
大規模なチームが複雑なクライアント側アプリケーションを保守している。 チームは、アプリケーションのセキュリティ 要件を満たす複数の Trusted Types ポリシーを作成する。チームはポリシーの 実装とそれを使用する安全な抽象化を、厳密にレビューされる少数の ファイルに集約し、これらのファイルに 影響するコミットには追加の承認を要求する。
インジェクションシンクに影響を与えるには信頼された値を作成する必要があることと、 ポリシーコードに影響する変更に対する追加の精査が組み合わさることで、 開発者は § 2.1.1 DOM XSS インジェクションシンクとやり取りする際に、その場限りの文字列合成コードを書く代わりに安全な抽象化を使用するよう促される。
DOM XSS のリスクを検討する際、セキュリティ監査担当者は 小さな攻撃面のみを確認すればよい。CSP ヘッダーを 構築し安全な抽象化を提供する少量のコードに集中し、 クライアント側アプリケーションコードの大部分を無視できる。
-
既存の Web アプリケーションは、主として XSS に対して安全な パターン(すなわち § 2.1.1 DOM XSS インジェクション シンクを使用しないパターン)を用いて DOM とやり取りしている。しかし一部では、 JSONP を使った追加スクリプトの読み込み、
innerHTMLやevalの呼び出しなど、危険なパターンを使用している。レビューにより、それらの箇所は XSS を引き起こさない(例えば、 ユーザーが制御するデータがそれらのシンクへの入力に含まれないため)ことが判明したが、 アプリケーションからこれらのパターンを排除することは困難である。
そのため、このアプリケーションでは CSP を強制できない(
'unsafe-eval' 'unsafe-inline'を使用する安全でないバージョンに頼らない限り)。さらに、 DOM XSS の欠陥を含むコードベースの一部がレビュー対象に含まれていなかった、 または将来導入される可能性もある。このリスクに対処するため、作者はレビュー済みの部分を Trusted Types を使用するよう変換し、Trusted Type の 強制を有効にする。将来、 インジェクションシンクを使用する箇所が追加で存在したとしても、適切に ブロックされ、報告される。
-
セキュリティチームが、クライアント側中心の アプリケーションコードに XSS 脆弱性が含まれていないことを保証する任務を担っている。サーバー側 コードは均質であり(主に API バックエンドである)、アプリケーションは Trusted Types を強制しているため、レビューでは Trusted Type の ポリシーとその規則だけに注目する。その後、 レビュー済みのポリシー名を 'trusted-types' CSP ディレクティブで許可し、開発者が安全に 使用できるようにする。
頻繁に変更される依存関係のコードを含むその他のコードは、 Trusted Type ポリシーを作成しない限り、レビューから除外できる。 ポリシーがなければ、そのコードは DOM XSS を引き起こせない。
2. フレームワーク
2.1. インジェクションシンク
この節は規範的ではない。
インジェクションシンクとは、 信頼され、検証され、または適切にサニタイズされた入力のみを使用して 呼び出すべき強力な Web API 関数である。 攻撃者が制御する(すなわち注入された)入力でインジェクションシンクを呼び出すと 望ましくない結果が生じ、セキュリティ脆弱性とみなされる。
注記: この文書が対象とするインジェクションシンクの正確な一覧は § 4 統合で定義される。
あるアプリケーションにこのような
脆弱性が含まれるかどうか(例えば DOM XSS に対して脆弱かどうか)を、インジェクション
シンクの呼び出しだけを解析して判断することは困難である。これは、その入力(通常は文字列)に
出所に関する情報が含まれないためである。例えば、
アプリケーションが動的に作成された入力で eval() を意図的に呼び出すことが
ある(例えばコード難読化のため)一方、攻撃者から提供された文字列に対して
eval() を呼び出すことは明らかにセキュリティ脆弱性である。しかし、
両者を容易に区別することはできない。
この文書では、特定のグループに属するシンクが持つ 機能に基づいてインジェクションシンクをグループに分類する。グループの 強制は、trusted-types-sink-group 値によって制御される。
2.1.1. DOM XSS インジェクションシンク
この節は規範的ではない。
DOM XSS インジェクションシンクは、 信頼できない値であれば DOM XSS を 引き起こし得る方法で入力文字列値を評価する。
例には次のものが含まれる:
-
Elementの、 読み込むコードの URL を受け入れる属性のセッター。 例えばHTMLScriptElement.src。 -
Elementの、 実行するコードを受け入れる属性のセッター。 例えばHTMLScriptElement.text。 -
evalのようにコードを直接実行する関数。 -
'javascript:' URL へのナビゲーション。
HTML パーサーはスクリプトを含む任意の要素を作成し、任意の属性を設定できるため、 DOM XSS インジェクションシンクには HTML 解析シンクも含まれる:
-
HTML 文字列を解析して文書に挿入する関数。 例えば
Element.innerHTML、ShadowRoot.innerHTML、 およびElement.outerHTMLのセッター、または Document.write。 -
呼び出し元が制御する マークアップを使用して、新しい同一オリジンの
Documentを作成する関数。 例えばparseFromString()。
DOM XSS インジェクションシンクの保護は、trusted-types-sink-group の 'script' という名前の値によって制御される。
2.2. Trusted Types
作者がインジェクションシンクへ到達する値を制御できるようにするため、 § 2.2 Trusted Typesを導入する。次に示す Trusted Type の一覧は、ある値が 特定のコンテキストで インジェクションシンクに使用してよいものとして作者から 信頼されていることを示す。
注記: この文脈での Trusted は、 アプリケーション作者が、 ある値をインジェクションシンクで安全に使用できると確信しており、その値が 脆弱性を導入しないと信頼していることを意味する。これは、その 値が実際に安全であることを意味しない。
注記: これにより作者は、ある 値を作成するときの意図を明示でき、 ユーザーエージェントはその値の型に基づく検査を導入して 作者の意図を維持できる。例えば、 作者がある値を HTML 断片として使用する意図を持つ場合、 その値からスクリプトを読み込もうとすると失敗する。
注記: すべての Trusted Type は、 オブジェクト作成時に指定される不変の文字列をラップする。これらのオブジェクトは、 指定されたオブジェクトの内部文字列値を置き換える JavaScript から公開された方法が 存在しないという意味で偽装不可能である。その値はセッターが 公開されていない内部スロットに格納される。
注記: すべての Trusted Type の文字列化処理は内部の 文字列値を返す。 これにより、アプリケーションコードを DOM 文字列の代わりに Trusted Types を使用するよう段階的に移行しやすくなる(アプリケーションの一部で 型の生成を開始しつつ、コードベースの別の部分では引き続き 文字列を使用および受け入れることができる)。この意味で、 Trusted Types は通常の DOM API と後方互換性がある。
2.2.1. TrustedHTML
TrustedHTML インターフェイスは、開発者が
HTML としてレンダリングする インジェクションシンクへ確信をもって挿入できる文字列を表す。
これらのオブジェクトは文字列を包む不変の
ラッパーであり、TrustedTypePolicy
の
createHTML
メソッドによって構築される。
[Exposed =(Window ,Worker )]interface TrustedHTML {stringifier ;DOMString toJSON (); };
TrustedHTML オブジェクトには、関連付けられた文字列 データがある。 値はオブジェクトの作成時に設定され、その存続期間中に変更されることはない。
toJSON() メソッドの手順と、
TrustedHTML オブジェクトの 文字列化の挙動の手順は、
関連付けられた データ値を返すことである。
2.2.2. TrustedScript
TrustedScript インターフェイスは、開発者が
そのスクリプトを実行する可能性のある インジェクションシンクへ確信をもって渡せる
未コンパイルのスクリプト本体を含む文字列を表す。
これらのオブジェクトは
文字列を包む不変のラッパーであり、TrustedTypePolicy
の
createScript
メソッドによって構築される。
[Exposed =(Window ,Worker )]interface TrustedScript {stringifier ;DOMString toJSON (); };
TrustedScript オブジェクトには、関連付けられた文字列 データがある。 値はオブジェクトの作成時に設定され、その存続期間中に変更されることはない。
toJSON() メソッドの手順と、
TrustedScript オブジェクトの 文字列化の挙動の手順は、
関連付けられた データ値を返すことである。
2.2.3. TrustedScriptURL
TrustedScriptURL インターフェイスは、開発者が
外部スクリプトリソースの URL として解析する インジェクションシンクへ確信をもって渡せる文字列を表す。
これらのオブジェクトは、
文字列を包む不変のラッパーであり、TrustedTypePolicy
の
createScriptURL
メソッドによって構築される。
[Exposed =(Window ,Worker )]interface TrustedScriptURL {stringifier ;USVString toJSON (); };
TrustedScriptURL オブジェクトには、関連付けられた文字列 データがある。 値はオブジェクトの作成時に設定され、その存続期間中に変更されることはない。
toJSON() メソッドの手順と、
TrustedScriptURL オブジェクトの 文字列化の挙動の手順は、
関連付けられた データ値を返すことである。
2.2.4.
TrustedHTMLParserOptions
TrustedHTMLParserOptions
インターフェイスは、開発者が
HTML を解析する インジェクションシンクへ確信をもって渡せるオプションを表す。
これらのオブジェクトは
SetHTMLUnsafeOptions
辞書を包む不変のラッパーであり、TrustedTypePolicy
の
createParserOptions
メソッドによって構築される。
[Exposed =Window ]interface TrustedHTMLParserOptions { };
TrustedHTMLParserOptions
オブジェクトには、関連付けられた boolean runScripts
と、関連付けられた SanitizerConfig-または-null
の
サニタイザー設定がある。
これらの値はオブジェクト作成時に設定され、その存続期間中に変更されることはない。
2.3. ポリシー
Trusted Types は、文字列を 特定の Trusted Type オブジェクトへ変換する規則を定義する、ユーザー定義かつ 不変のポリシーを介してのみ作成できる。ポリシーによって作者は、 Trusted Types が従わなければならない独自のプログラム的規則を指定できる。
TrustedHTML
オブジェクトは、その後アプリケーション内で
安全に使用でき、例えば innerHTML セッターへ渡せる。入力値が攻撃者に
制御されていた場合でも、ポリシーの規則によって
ポリシー固有の契約に従うよう無害化される。
const sanitizingPolicy= trustedTypes. createPolicy( 'sanitize-html' , { createHTML: ( input) => myTrustedSanitizer( input, { superSafe: 'ok' }), }); myDiv. innerHTML= sanitizingPolicy. createHTML( untrustedValue);
注記: Trusted Type オブジェクトは、作者が明示的に信頼した値をラップする。 したがって、Trusted Type オブジェクトインスタンスの作成自体が事実上の インジェクションシンクとなり、 Trusted Type インスタンスを作成するコードは セキュリティ上重要になる。Trusted Type オブジェクトの作成を厳密に制御できるようにするため、これらのコンストラクターは 直接公開せず、作者に ポリシーを介して作成することを要求する。
特定の Realm 内には複数のポリシーを作成でき、 アプリケーションはコードベースの異なる部分に対して 異なる規則を定義できる。
const cdnScriptsPolicy= trustedTypes. createPolicy( 'cdn-scripts' , { createScriptURL( url) { const parsed= new URL( url, document. baseURI); if ( parsed. origin== 'https://mycdn.example' ) { return url; } throw new TypeError ( '無効な URL' ); }, }); myLibrary. init({ policy: cdnScriptsPolicy});
注記: Trusted Type オブジェクトは
ポリシーを介してのみ作成できる。
強制が有効な場合、
ポリシーコードだけが インジェクションシンクの
動作を引き起こすことができ、
したがってポリシーの create* 関数の呼び出し箇所は、
インジェクションシンクの動作に関して、プログラム全体で唯一のセキュリティ上重要なコードである。
コードベース全体のうち通常は小さなこの部分だけを
セキュリティレビューすればよく、
インジェクションシンク
自体を監視またはレビューする必要はない。ユーザーエージェントが
強制するためであり、
それらのシンクは一致する Trusted Type オブジェクトだけを受け入れ、
それらのオブジェクトもポリシーを介してのみ作成できる。
createPolicy
関数はポリシーオブジェクトを返し、その create* 関数は
ポリシーの規則を適用した後に Trusted Type オブジェクトを
作成する。
注記: 入力をサニタイズするポリシーは
アプリケーション内のどこででも自由に安全に使用できる一方、
内部でのみ使用し、作者が制御する入力でのみ
呼び出す緩いポリシーを作成する必要がある場合もある。例えば、クライアント側 HTML
テンプレートライブラリ、HTML サニタイザーライブラリ、または JS の非同期
コードプラグイン読み込みサブシステムは、それぞれ HTML や URL を完全に制御する必要があるだろう。
API の設計はそれを容易にする。各ポリシーは、呼び出し箇所がポリシーへの参照(
createPolicy()の戻り値)を取得できる場合にのみ
使用できる。
そのため、ポリシーへの参照は
ケイパビリティとして扱うことができ、
そのアクセスは JavaScript の技法
(例えばクロージャ、内部関数変数、モジュール)を用いて制御できる。
( async function renderFootnote() { const unsafePolicy= trustedTypes. createPolicy( 'html' , { createHTML: input=> input, }); const footnoteContent= await fetch( '/footnote.html' ). then( r=> r. text()); footNote. innerHTML= unsafePolicy. createHTML( footnoteContent); })();
2.3.1. サニタイザーとの併用
Trusted Types は独自のサニタイザーを使用できるように構築されているが、
createParserOptions
は、組み込みのサニタイザー API の使用を
強制する手段として利用することもできる。
( async function renderFootnote() { const footnoteContent= await fetch( '/footnote.html' ). then( r=> r. text()); const policy= trustedTypes. createPolicy( 'html' , { createParserOptions: options=> { const sanitizer= new Sanitizer( options. sanitizer? . get() ?? {}); sanitizer. removeUnsafe(); return { sanitizer, }; } }); footNote. setHTMLUnsafe( footnoteContent, policy. createParserOptions({})); })();
注記: マークアップを解析する HTML インジェクション
シンク(例えば setHTMLUnsafe()
または innerHTML)に
Trusted Types を強制する場合、
TrustedHTMLParserOptions
オブジェクト(createParserOptions
から取得するか、デフォルトポリシーによって提供されるもの)により、未加工の文字列を直接解析でき、
createHTML
や TrustedHTML
インスタンスを必要としない。ポリシー作者は通常、createParserOptions
でサニタイザーを設定し、信頼できないマークアップが解析時にサニタイズされるようにする。パーサーオプションをサポートしない
文字列専用インジェクションシンク
(例えば srcdoc
や document.write())、または XML 文書では、未加工の文字列を引き続き createHTMLによって変換しなければならない。
2.3.2.
TrustedTypePolicyFactory
TrustedTypePolicyFactory は
ポリシー
を作成し、Trusted Type オブジェクトインスタンスが
いずれかのポリシーを介して作成されたことを検証する。
注記: このファクトリーオブジェクトは、
グローバルオブジェクトの trustedTypes プロパティを通じて JavaScript に公開される。
§ 4.1.1
WindowOrWorkerGlobalScope インターフェイスの拡張を参照。
[Exposed =(Window ,Worker )]interface TrustedTypePolicyFactory {TrustedTypePolicy createPolicy (DOMString ,policyName optional TrustedTypePolicyOptions = {});policyOptions boolean isHTML (any );value boolean isScript (any );value boolean isScriptURL (any );value readonly attribute TrustedHTML emptyHTML ;readonly attribute TrustedScript emptyScript ;DOMString ?getAttributeType (DOMString ,tagName DOMString ,attribute optional DOMString ?= "",elementNs optional DOMString ?= "");attrNs DOMString ?getPropertyType (DOMString ,tagName DOMString ,property optional DOMString ?= "");elementNs readonly attribute TrustedTypePolicy ?defaultPolicy ; };
TrustedTypePolicyFactory
オブジェクトには、関連付けられた TrustedTypePolicy
デフォルトポリシーがある。
その値は初期状態では null である。
TrustedTypePolicyFactory
オブジェクトには、文字列の 有順集合である 作成済みポリシー名が関連付けられている。
その値は初期状態では « » である。
createPolicy(policyName, policyOptions)-
TrustedTypePolicyOptionspolicyOptions オブジェクトで渡された規則を 実装するポリシーオブジェクトを作成する。 許可されるポリシー名は コンテンツ セキュリティポリシーによって制限される場合がある。 ポリシー名が trusted-types CSP ディレクティブで定義された許可リストにない場合、 ポリシーの作成は TypeError により失敗する。 また、一意なポリシー名が強制されている場合(すなわち'allow-duplicates'が使用されていない場合)、 任意のpolicyNameについてcreatePolicyが複数回呼び出されると、 ポリシーの作成は TypeError により失敗する。// HTTP 応答ヘッダー: Content-Security-Policy: trusted-types foo trustedTypes. createPolicy( "foo" , {}); // OK。 trustedTypes. createPolicy( "bar" , {}); // 例外をスロー - 名前が許可リストにない。 trustedTypes. createPolicy( "foo" , {}); // 例外をスロー - 名前が重複している。 Trusted Type ポリシーを作成するアルゴリズムを 次の引数で実行した結果を返す:
- factory
- this 値
- policyName
- policyName
- options
- policyOptions
- global
- this 値の 関連するグローバルオブジェクト
const myPolicy= trustedTypes. createPolicy( 'myPolicy' , { // このセキュリティ上重要なコードにはセキュリティレビューが必要である。 // このコードの欠陥は DOM XSS を引き起こす可能性がある。 createHTML( input) { return aSanitizer. sanitize( input) }, createScriptURL( input) { const u= new URL( dirty, document. baseURI); if ( APPLICATION_CONFIG. scriptOrigins. includes( u. origin)) { return u. href; } throw new Error ( 'このオリジンからスクリプトを読み込めない' ); }, }); document. querySelector( "#foo" ). innerHTML= myPolicy. createHTML( aValue); scriptElement. src= myPolicy. createScriptURL( 'https://scripts.myapp.example/script.js' ); isHTML(value)-
value が
TrustedHTMLのインスタンスであり、関連付けられた データ値が設定されている場合は true を、それ以外の場合は false を返す。注記:
is*関数は、あるオブジェクトが 真に正当な Trusted Type オブジェクト (すなわち設定されたポリシーのいずれかを介して作成されたもの)であるかを 検査するために使用される。これは、例えば Object.create やプロトタイプチェーンの操作によるオブジェクトの偽装を検出できるようにするためである。 isScript(value)-
value が
TrustedScriptのインスタンスであり、関連付けられた データ値が設定されている場合は true を、それ以外の場合は false を返す。 isScriptURL(value)-
value が
TrustedScriptURLのインスタンスであり、関連付けられた データ値が設定されている場合は true を、それ以外の場合は false を返す。 getPropertyType(tagName, property, elementNs)-
作者が、指定した
Elementの プロパティ(IDL 属性)に Trusted Type が必要かどうかを確認できるようにする。この関数は、次のアルゴリズムの結果を返す:
-
localName を、tagName を ASCII 小文字にしたものに設定する。
-
elementNs が null または空文字列なら、elementNs を HTML 名前空間に設定する。
-
interface を、 localName と elementNs に対する 要素インターフェイスとする。
-
expectedType を null とする。
-
次の表から、第1列が "*" または interface の名前であり、かつ property が第2列にある行を探す。 一致する行が見つかった場合、expectedType を 第3列の値であるインターフェイスの名前に設定する。
要素 プロパティ名 TrustedType HTMLIFrameElement"srcdoc" TrustedHTMLHTMLScriptElement"innerText" TrustedScriptHTMLScriptElement"src" TrustedScriptURLHTMLScriptElement"text" TrustedScriptHTMLScriptElement"textContent" TrustedScript"*" "innerHTML" TrustedHTML"*" "outerHTML" TrustedHTML -
expectedType を返す。
-
getAttributeType(tagName, attribute, elementNs, attrNs)-
作者が、指定した
Elementの 内容属性に Trusted Type が必要かどうか、また必要ならどの Trusted Type かを確認し、後でElement.setAttributeの呼び出しに正しい引数型を渡せるようにする。この関数は、次のアルゴリズムの結果を返す:
-
localName を、tagName を ASCII 小文字にしたものに設定する。
-
attribute を、attribute を ASCII 小文字にしたものに設定する。
-
elementNs が null または空文字列なら、elementNs を HTML 名前空間に設定する。
-
attrNs が空文字列なら、attrNs を null に設定する。
-
interface を、 localName と elementNs に対する 要素インターフェイスとする。
-
expectedType を null とする。
-
attributeData を、次の引数で 属性の Trusted Type データを取得するアルゴリズムを実行した結果に設定する:
-
element として interface
-
attribute
-
attrNs
-
-
attributeData が null でない場合、expectedType を attributeData の第4メンバーの値であるインターフェイスの名前に設定する。
-
expectedType を返す。
-
emptyHTML, 型は TrustedHTML、 読み取り専用-
データ値が空文字列に設定された
TrustedHTMLオブジェクトである。
emptyScript, 型は TrustedScript、読み取り専用-
データ値が空文字列に設定された
TrustedScriptオブジェクトである。
注記: このオブジェクトは、
実行環境が動的コードコンパイルをサポートしているかどうかを検出するために使用できる。
ネイティブの Trusted Types 実装は eval(TrustedScript) をサポートできるが、
polyfill では
eval(TrustedScript) が入力をアンラップしてコードを評価せず、そのまま返すため、これを
エミュレートすることは不可能である。
// ネイティブの Trusted Types をサポートしている場合、eval(trustedTypes.emptyScript) は実行され、falsy な undefined を返す。 // サポートしていない場合、eval(trustedTypes.emptyScript) は truthy な Object を返す。 const supportsTS= ! eval( trustedTypes. emptyScript); eval( supportsTS? myTrustedScriptObj: myTrustedScriptObj. toString());
defaultPolicy, 型は TrustedTypePolicy、読み取り専用、nullable-
デフォルトポリシーの値を返す。
2.3.3. TrustedTypePolicy
ポリシーオブジェクトは TrustedTypePolicy インターフェイスを実装し、
Trusted Type オブジェクトを作成する一連の関数を定義する。
各 create* 関数は文字列値を特定の Trusted Type の種類に変換するか、
指定された値の変換が許可されていない場合は TypeError をスローする。
[Exposed =(Window ,Worker )]interface TrustedTypePolicy {readonly attribute DOMString ;name TrustedHTML createHTML (DOMString ,input any ...);arguments TrustedScript createScript (DOMString ,input any ...);arguments TrustedScriptURL createScriptURL (DOMString ,input any ...); [arguments Exposed =Window ]TrustedHTMLParserOptions createParserOptions (optional SetHTMLUnsafeOptions = {},options any ...); };arguments
各ポリシーには 名前がある。
各 TrustedTypePolicy オブジェクトには、関連付けられた TrustedTypePolicyOptions
オプションオブジェクトがあり、ポリシーの実際の挙動を記述する。
createHTML(input, ...arguments)-
次の引数で Trusted Type を作成するアルゴリズムを実行した 結果を返す:
- policy
- this 値
- trustedTypeName
"TrustedHTML"- value
- input
- arguments
- arguments
createScript(input, ...arguments)-
次の引数で Trusted Type を作成するアルゴリズムを実行した 結果を返す:
- policy
- this 値
- trustedTypeName
"TrustedScript"- value
- input
- arguments
- arguments
createScriptURL(input, ...arguments)-
次の引数で Trusted Type を作成するアルゴリズムを実行した 結果を返す:
- policy
- this 値
- trustedTypeName
"TrustedScriptURL"- value
- input
- arguments
- arguments
createParserOptions(options, ...arguments)-
次の引数で Trusted Type を作成するアルゴリズムを実行した 結果を返す:
- policy
- this 値
- trustedTypeName
"TrustedHTMLParserOptions"- value
- options
- arguments
- arguments
2.3.4.
TrustedTypePolicyOptions
この辞書は、文字列値を
信頼された値へ変換するための作者定義の関数を保持する。これらの関数は Trusted Type
オブジェクトインスタンスを直接作成しない。この挙動は
TrustedTypePolicyによって提供される。
dictionary TrustedTypePolicyOptions {CreateHTMLCallback ;createHTML CreateScriptCallback ;createScript CreateScriptURLCallback ;createScriptURL CreateParserOptionsCallback ; };createParserOptions callback =CreateHTMLCallback DOMString ? (DOMString ,input any ...);arguments callback =CreateScriptCallback DOMString ? (DOMString ,input any ...);arguments callback =CreateScriptURLCallback USVString ? (DOMString ,input any ...);arguments callback =CreateParserOptionsCallback SetHTMLUnsafeOptions ? (SetHTMLUnsafeOptions ,options any ...);arguments
2.3.5. デフォルトポリシー
この節は規範的ではない。
ポリシーのうち、名前が
"default" であるポリシーは特別である。
インジェクションシンクに
(Trusted Type オブジェクトではなく)文字列が渡されると、
このポリシーはユーザーエージェントによって暗黙に呼び出され、
信頼されていない文字列値、シンクの Trusted Type、
シンク型がそれぞれ渡される。
これにより、アプリケーションは違反を発生させる代わりに使用する フォールバックの挙動を定義できる。その意図は、アプリケーションが予期しない データフローから回復し、 攻撃者に制御される可能性のある文字列を「最後の手段として」サニタイズするか、 安全な値を作成できない場合に値を拒否できるようにすることである。ポリシー内でスローされたエラーは アプリケーションへ伝播する。
デフォルトポリシーが存在しない場合、または適切な create* 関数が
null または undefined を返す場合、CSP 違反が発生する。
強制モードではエラーがスローされるが、report-only ではデフォルトポリシーに渡された
元の値が使用される。
注記: この任意の挙動により、 インジェクションシンクを使用するレガシーコードをまだ使用しているアプリケーションにも Trusted Type の 強制を導入できる。 言うまでもなく、このポリシーは、 アプリケーションの未知の部分でセキュリティ 制限を回避しないよう、必ず非常に厳格な規則で定義すべきである。極端な 場合、制約の緩い no-op デフォルトポリシーは、Trusted Types を インジェクション シンクへのアクセス保護に使用する利点をすべて無効にする。可能であれば、 作者は移行期間にのみデフォルトポリシーを使用し、 それを用いてインジェクション シンクを安全でない方法で使用する依存関係を検出して書き換え、最終的にはデフォルトポリシーの使用を完全に廃止すべきである。
注記: デフォルトポリシーの適用方法の 詳細については、§ 3.5 Trusted Type 準拠の文字列を取得するを 参照。
// Content-Security-Policy: trusted-types default; require-trusted-types-for 'script' trustedTypes. createPolicy( 'default' , { createScriptURL: ( value, type, sink) => { console. log( "リファクタリングしてください。" ); return value+ '?default-policy-used&type=' + encodeURIComponent( type) + '&sink=' + encodeURIComponent( sink); } }); aScriptElement. src= "https://cdn.example/script.js" ; // リファクタリングしてください。 console. log( aScriptElement. src); // https://cdn.example/script.js?default-policy-used&type=TrustedScriptURL&sink=HTMLScriptElement%20src
2.4. 強制
注記: 強制とは、値が インジェクションシンクへ到達する前に適切な型を持っていることを確認する処理である。
作者がポリシーとそこから Trusted Types オブジェクトを作成できる JavaScript API は常に
利用可能である(trustedTypesを介して)。
インジェクションシンクは
セキュリティ上重要な引数を文字列化し、
Trusted Type
オブジェクトは内部の文字列値へ文字列化されるため、作者は
文字列の代わりに Trusted Types を使用できる。
インジェクションシンクへのアクセスを保護するには、Trusted Types を使用する JavaScript コードに加えて、 ユーザーエージェントがそれらを強制する必要がある。すなわち、指定されたグループのインジェクションシンクが 決して 文字列値で呼び出されず、代わりに Trusted Type 値が使用されることを保証する。この節では、作者が この強制の挙動を制御する方法を説明する。
作者は、ポリシー作成に関する規則を指定することで、 ポリシーを制御することもできる。
2.4.1. コンテンツセキュリティポリシー
アプリケーションは、コンテンツセキュリティポリシーを設定することで Trusted Type の強制を制御できる。この 文書では、Trusted Types の規則に対応する新しいディレクティブを定義する。 require-trusted-types-for ディレクティブは、 型を要求すべき インジェクションシンクのグループを 指定する。trusted-types ディレクティブは ポリシーをどのように作成できるかを制御する。
注記: CSP の仕組みを使用すると、作者は Content-Security-Policy-Report-Only HTTP 応答ヘッダーを使用して、Trusted Types の強制に向けてアプリケーションを準備できる。
注記: 強制規則の大部分は 他の仕様のアルゴリズムに対する変更として定義される。§ 4 統合を参照。
2.4.2.
createParserOptionsによるサニタイズの強制
createHTML
は JS サニタイザーを使用してパーサーへ注入する前に文字列をサニタイズすることに依存する一方、
createParserOptions
は、ページのデフォルトポリシーによって HTML のサニタイズを強制できる。
デフォルトポリシー内の createParserOptions
コールバックは、
未審査のパーサーオプション(またはデフォルトオプション)で HTML 断片シンクが呼び出されるたびに実行され、
ポリシーが呼び出し元から渡されたオプションを審査し、
入力マークアップがすでに TrustedHTML
のインスタンスであってもサニタイズを強制できる。
Content-Security-Policy: require-trusted-types-for 'script'
HTML インジェクションシンクを使用する際にサニタイザーを注入する。
( async function renderFootnote() { trustedTypes. createPolicy( 'default' , { createParserOptions: options=> { const sanitizer= new Sanitizer( options. sanitizer? . get() ?? {}); sanitizer. removeUnsafe(); return { ... options, sanitizer}; } }); const trustedOptions= trustedTypes. createPolicy( 'trusted' , { createParserOptions: options=> options}). createParserOptions({}); const untrustedFootnoteContent= await fetch( '/footnote.html' ). then( r=> r. text()); // デフォルトポリシーが注入するため、この HTML は「安全な」HTML サニタイザーでサニタイズされる // 安全でないマークアップを除去するサニタイザー。 footNote. innerHTML= untrustedFootnoteContent; // または: footNote. setHTMLUnsafe( untrustedFootnoteContent, {}); const trustedMainContent= await fetch( "main.html" ). then( r=> r. text()); main. setHTMLUnsafe( trustedMainContent, trustedOptions); })();
サニタイズに加えて、デフォルトポリシーは HTML インジェクションがスクリプトを実行するかどうかも
呼び出し元の runScripts
設定を上書きすることで制御できる。
runScripts
を false に設定して挿入された HTML でも、文書内に script 要素を挿入できるが、
それらのスクリプトは自動的には実行されない。
( async function renderFootnote() { trustedTypes. createPolicy( 'default' , { createHTML: string=> string, createParserOptions: options=> { return { ... options, runScripts: false }; } }); // デフォルトポリシーは runScripts の値を false に上書きする。 main. setHTMLUnsafe( someHTMLWithScripts, { runScripts: true }); // これは Range.prototype.createContextualFragment() にも適用される const fragment= new Range(). createContextualFragment( "<script>alert(1)</" + "script>" ); const div= document. createElement( 'div' ); // デフォルトポリシーが runScripts を上書きするため、断片内のスクリプトは実行されない。 div. appendChild( fragment); })();
2.4.3. 入力強制の概要
この節は規範的ではない。
次の表は、強制中のコンテンツセキュリティポリシーの下で、 Trusted Type 準拠の入力を取得するについて、引数とデフォルトポリシーコールバックのさまざまな組み合わせに対する挙動をまとめたものである:
| documentType | options | input | デフォルトポリシーの状態 / コールバック | 結果 | 有効な sanitizer
| 根拠 |
|---|---|---|---|---|---|---|
"html"
| TrustedHTMLParserOptions
| 文字列または TrustedHTML
| (無視) | (stringified |input|, |options|)を返す。
| options の サニタイザー設定 | 呼び出し元から渡された TrustedHTMLParserOptions
は解析操作を明示的に許可し、スクリプト実行とサニタイズは
それを生成したポリシーによって決定される。
|
"html"
| 辞書(呼び出し元が sanitizer を提供)
| TrustedHTML
| createParserOptions
がポリシーサニタイザーを設定する辞書を返す
| (stringified |input|, |compliantOptions|)を返す。
| createParserOptions
によって設定
| ポリシーが TrustedHTML 上の呼び出し元のサニタイザーを審査または置換する:
input が証明済みの TrustedHTML
インスタンスであっても、createParserOptions
は実行され、argument["sanitizer"]で呼び出し元のサニタイザーを受け取る。ポリシーは
サニタイザー設定を検査、強制、または置換でき(スクリプト実行も制御でき)、
未審査の呼び出し元提供オプションがポリシーレビューを回避できないようにする。
|
辞書(呼び出し元が sanitizer を提供)
| createParserOptions
が {} を返す(サニタイザーを省略)
| (stringified |input|, |compliantOptions|)を返す。
| null
| ポリシーが呼び出し元のサニタイザーを除去する: デフォルトポリシーが最終的な パーサーオプションを決定する。ポリシーがサニタイザーを返さなければ、解析中にサニタイズは行われず、 呼び出し元の要求を上書きする。 | ||
| 作者から提供されたものではない、または 審査を 必要としない辞書 | createParserOptionsがない
(またはデフォルトポリシーがない)
| (stringified |input|, |options|)を返す。
| null
| パーサーポリシーのない TrustedHTML: createParserOptions
を定義するポリシーがない場合、既存の TrustedHTML
インスタンスは Trusted Types を直接満たす(createHTMLを迂回する)。
ただし作者から提供されたオプションが審査を必要としない場合に限る。
| ||
| 審査を必要とする作者提供の辞書 | TypeErrorをスローする。
| N/A | 未審査のオプションを拒否: TrustedHTML
は未審査のサニタイザーやスクリプト実行によって安全でなくなる可能性があるため、これらのオプションには TrustedHTMLParserOptions
またはデフォルトポリシーの createParserOptionsが必要である。
| |||
"html"
| 辞書 | 文字列 | createParserOptions
が辞書を返す
| (stringified |input|, |compliantOptions|)を返す。
| createParserOptions
により設定(または null)
| パーサーポリシーによって未加工文字列の解析が許可される: デフォルトポリシーが
準拠するパーサーオプションを返すことで、未加工文字列の解析を許可し、
createHTMLを必要とせずにサニタイズとスクリプト
実行を設定する。
|
| 辞書 | 文字列または TrustedHTML
| createParserOptions
が例外をスローする
| 例外を再スローする。 | N/A | ポリシーコールバック内の例外は、input が文字列であるか
TrustedHTMLであるかにかかわらず、直ちに呼び出し元へ伝播する。
| |
createParserOptions
が null または undefined を返す
| TypeErrorをスローする。
| N/A | ポリシーコールバックから null または undefined を返すと値が拒否され、CSP 違反
エラーが発生する。これは input が文字列であるか TrustedHTMLであるかにかかわらない。
| |||
| 審査を必要とする作者提供の辞書 | 文字列 | createParserOptionsがない
(またはデフォルトポリシーがない)
| TypeErrorをスローする。
| N/A | 未審査のオプションを拒否: createHTML
は呼び出されない。その結果は未審査のオプションを使用して解析されることになるためである。
| |
| 作者から提供されたものではない、または 審査を 必要としない辞書 | 文字列 | createParserOptionsがない。
createHTML
が TrustedHTML
を返す
| (stringified |convertedInput|, |options|)を返す。
| null
| 後方互換性を提供する。パーサーオプションを管理するポリシーがない場合、
シンクは createHTMLを介してマークアップ文字列を
審査またはサニタイズする方法にフォールバックする。
| |
createParserOptionsがない。
createHTML
が例外をスローする
| 例外を再スローする。 | N/A | ポリシーコールバック内の例外は直ちに呼び出し元へ伝播する。 | |||
createParserOptionsがない。
createHTML
が null または undefined を返す
| TypeErrorをスローする。
| N/A | createHTML
による拒否は CSP 違反エラーを引き起こす。
| |||
| デフォルトポリシーがない(またはいずれのコールバックも定義されていない) | TypeErrorをスローする。
| N/A | CSP の強制下では、パーサーオプションまたは マークアップ文字列のいずれかを許可するポリシーなしに未加工文字列を解析できない。 | |||
"xml"
| 任意 | TrustedHTML
| (任意) | (stringified |input|, |options|)を返す。
| なし(無視) | XML シンクには信頼されたマークアップが必要であり、TrustedHTML
インスタンスはこの要件を直接満たす。XML 断片の解析はサニタイズをサポートせず、
スクリプトを実行することもない。
|
"xml"
| 任意 | 文字列 | createHTML
が TrustedHTML
を返す
| (stringified |convertedInput|, |options|)を返す。
| なし(無視) | XML 断片シンクはパーサーオプションによる回避やサニタイズをサポートしないため、マークアップ文字列は
必ず createHTMLを介して変換しなければならない。
XML 断片の解析はサニタイズをサポートせず、スクリプトを実行することもない。
|
createHTML
が例外をスローする
| 例外を再スローする。 | N/A | ポリシーコールバック内の例外は直ちに呼び出し元へ伝播する。 | |||
createHTMLがない、
またはデフォルトポリシーがない(あるいは null/undefined を返す)
| TypeErrorをスローする。
| N/A | 信頼されていない文字列は createHTMLなしに
XML シンクへ
注入できず、これはパーサーオプションにかかわらない。
|
TrustedHTML、runScripts、およびサニタイズ: Trusted Types を強制するシンクは、オプションと スクリプトを次のように扱う:
- input が
TrustedHTMLインスタンスである場合でも、デフォルトポリシーのcreateParserOptionsは、呼び出し元から提供されたオプション辞書を引き続き審査し、入力がすでにTrustedHTMLであっても、ポリシーが サニタイザー設定を検査、設定、または上書きできる(スクリプト実行も制御できる)。createParserOptionsが例外をスローするかnullまたはundefinedを返す場合、操作は拒否される。createParserOptionsが存在しない場合、審査を必要とする作者提供のオプション辞書は、 input がTrustedHTMLインスタンスであるか、createHTMLによって変換された文字列であるかにかかわらず 拒否される。createContextualFragment()のrunScriptsを true に設定する場合のように、シンク自体が構築するオプションは拒否されない。 - options が
TrustedHTMLParserOptionsである場合、 スクリプト実行とサニタイズはオプションオブジェクトを作成したポリシーによって管理される。 オプションが辞書として渡される場合、デフォルトポリシーのcreateParserOptionsが最終的なスクリプト実行の挙動を決定し、呼び出し元が要求したrunScripts設定を上書きする。 - XML 断片の解析はサニタイズをサポートしないため、XML シンクではサニタイザー設定はすべて無視される。
- ストリーミング HTML 断片解析では、Trusted Type 準拠のパーサーオプションを取得する
が throwIfMissing を true に設定して直接呼び出される。この文脈では、
createParserOptionsが存在しない、例外をスローする、またはnullもしくはundefinedを返す場合、TypeErrorが直ちにスローされる(または再スローされる)。
3. アルゴリズム
3.1. Trusted Type ポリシーを作成する
Trusted Type
ポリシーを作成するには、TrustedTypePolicyFactory
(factory)、
文字列 (policyName)、TrustedTypePolicyOptions
辞書 (options)、および
グローバルオブジェクト (global) が与えられたとき、次の手順を実行する:
-
allowedByCSP を、Trusted Type ポリシーの作成を コンテンツセキュリティポリシーによってブロックすべきか?アルゴリズムを、 global、 policyName および factory の 作成済みポリシー名値を使用して実行した結果とする。
-
allowedByCSP が
"Blocked"なら、TypeError をスローし、以降の手順を中止する。 -
policyName が
defaultであり、factory の デフォルトポリシー 値が null でないなら、TypeError をスローし、以降の手順を中止する。 -
policy を新しい
TrustedTypePolicyオブジェクトとする。 -
policy の
nameプロパティ値を policyName に設定する。 -
policy の オプション値を «[ "createHTML" -> options["
createHTML"], "createScript" -> options["createScript"], "createScriptURL" -> options["createScriptURL"], "createParserOptions" -> options["createParserOptions"] ]» に設定する。 -
policyName が
defaultなら、factory の デフォルトポリシー値を policy に設定する。 -
policy を返す。
3.2. Trusted Type を作成する
Trusted
Type を作成するには、TrustedTypePolicy
policy、型名 trustedTypeName、
文字列または辞書 value、およびリスト arguments が与えられたとき、次の手順を実行する:
-
policyValue を、このアルゴリズムと同じ引数に加えて throwIfMissing として true を指定して Trusted Type ポリシー値を取得するを実行した結果とする。
-
アルゴリズムがエラーをスローした場合、そのエラーを再スローし、以降の手順を中止する。
-
trustedTypeName が
"TrustedHTMLParserOptions"なら:-
policyValue が null なら、
TypeErrorをスローする。注記: 名前付きポリシーの
createParserOptionsコールバックからnullを返すと、ここでTypeErrorがスローされる一方、createHTML、createScript、 またはcreateScriptURLからnullまたはundefinedを返すと空文字列になる。 -
sanitizerConfig を、 policy の 関連する Realmおよび policyValue から サニタイザー 設定を取得する結果とする。
-
runScripts を、policyValue["runScripts"] の デフォルトを false とした値とする。
-
policy の 関連する Realmで、新しい
TrustedHTMLParserOptionsインスタンスを返し、その サニタイザー 設定を sanitizerConfig に設定し、その runScripts を runScripts に設定する。
-
-
dataString を policyValue を文字列化した結果とする。
-
policyValue が null または undefined なら、dataString を空文字列に設定する。
-
型名が trustedTypeName であり、関連付けられたデータ値を dataString に設定したインターフェイスの新しいインスタンスを返す。
3.3. Trusted Type ポリシー値を取得する
Trusted
Type ポリシー値を取得するには、TrustedTypePolicy
policy、型名 trustedTypeName、
文字列または辞書 value、リスト arguments、および boolean
throwIfMissing が与えられたとき、次の手順を実行する:
-
functionName を、指定された trustedTypeName に対する関数名として、 次の表に基づいて決定する:
関数名 Trusted Type 名 "createHTML" "TrustedHTML" "createScript" "TrustedScript" "createScriptURL" "TrustedScriptURL" "createParserOptions" "TrustedHTMLParserOptions" -
function を policy の オプション[functionName] とする。
-
function が
nullなら:-
throwIfMissing なら TypeError をスローする。
-
そうでなければ
nullを返す。
-
-
trustedTypeName が
"TrustedHTMLParserOptions"なら:-
value を、policy の 関連する Realmおよび value が与えられたときに パーサーオプション コールバック引数を作成する結果に設定する。
-
-
args を « value » とする。
-
arguments の各項目を args に 付加する。
-
policyValue を、function を args および
"rethrow"とともに 呼び出した結果とする。 -
policyValue を返す。
3.4. Trusted Type 準拠の入力を取得する
注記: 引数とデフォルトポリシーコールバックのさまざまな組み合わせに対する このアルゴリズムの挙動の概要については、§ 2.4.3 入力強制の概要を参照。
Trusted
Type 準拠の入力を取得するには、グローバルオブジェクト global、文字列または TrustedHTML
input、
TrustedHTMLParserOptions、
ParseHTMLUnsafeOptions
または SetHTMLUnsafeOptions
options、文字列 sink、任意の "html" または "xml"
documentType(デフォルトは "html")、および任意の boolean optionsFromAuthor
(デフォルトは true)が与えられたとき:
-
compliantOptions を options とする。
-
documentType が
"html"なら:-
compliantOptions を、global、options、false、 sink、および optionsFromAuthor を渡して Trusted Type 準拠の パーサーオプションを取得するを呼び出した結果に設定する。
注記: 作者から受け取るのではなく、 options を自身で構築するシンクは、 optionsFromAuthor に false を渡す。 例えば、
createContextualFragment()はrunScriptsを true に設定する。 -
compliantOptions が
TrustedHTMLParserOptionsのインスタンスなら、(文字列化した input, compliantOptions) を返す。
-
-
compliantHTML を、
TrustedHTML、 global、input、sink、および"script"を渡して Trusted Type 準拠の文字列を取得するを呼び出した結果とする。 -
アルゴリズムがエラーをスローした場合、そのエラーを再スローする。
-
(compliantHTML, compliantOptions) を返す。
3.5. Trusted Type 準拠の文字列を取得する
このアルゴリズムは、インジェクションシンクで 使用できる文字列を返し、必要に応じて一致する Trusted Type からアンラップする。 また、Trusted Type の 強制規則が尊重されたことを保証する。
Trusted
Type 準拠の文字列を取得するには、TrustedType
型 (expectedType)、グローバルオブジェクト (global)、
TrustedType
または文字列 (input)、文字列 (sink) および文字列 (sinkGroup) が与えられたとき、次の
手順を実行する:
-
input が expectedType のインスタンスなら、文字列化した input を返し、これらの手順を中止する。
-
requireTrustedTypes を、global、sinkGroup、および true を渡して シンク型は Trusted Types を必要とするか? アルゴリズムを実行した結果とする。
-
requireTrustedTypes が
falseなら、文字列化した input を返し、 これらの手順を中止する。 -
convertedInput を、このアルゴリズムと同じ引数で デフォルトポリシーで値を処理するを実行した 結果とする。
-
アルゴリズムがエラーをスローした場合、そのエラーを再スローし、以降の手順を中止する。
-
convertedInput が
nullまたはundefinedなら、次の 手順を実行する:-
disposition を、global、sink、sinkGroup、および 文字列化した input を source として渡して シンク型不一致違反を コンテンツセキュリティポリシーによってブロックすべきか?アルゴリズムを実行した結果とする。
-
disposition が
“Allowed”なら、文字列化した input を返し、 以降の手順を中止する。注記: この手順により、デフォルト ポリシーによる拒否は報告されるが、report-only モードでは無視されることが保証される。
-
TypeError をスローし、以降の手順を中止する。
-
-
表明: convertedInput は expectedType のインスタンスである。
-
文字列化した convertedInput を返す。
3.6. Trusted Type 準拠のパーサーオプションを取得する
注記: Trusted Type
準拠の入力を取得するから呼び出される場合、
throwIfMissing は false である。その場合でも、
審査が必要な作者提供のオプションには、createParserOptionsを持つデフォルトポリシーが必要である。
同期 HTML 断片インジェクションシンクでは、結果として得られるオプション内の TrustedHTMLParserOptions
によって、入力文字列に createHTML
を要求することなく Trusted Types の強制を満たすことができる。
ストリーミング時、または HTML 文字列を事前に検証できないコンテキストでは、呼び出し元は
throwIfMissing に true を渡し、createParserOptionsを持つデフォルトポリシーが
必須になるようにする。
XML 文書では、パーサーオプションによって Trusted Types の強制を満たすことはできず、XML 断片シンクは常に
Trusted Type 準拠の文字列を取得するによる準拠した文字列入力を必要とする。
Trusted Type 準拠のパーサーオプションを取得するには、
グローバルオブジェクト global、
TrustedHTMLParserOptions、
SetHTMLUnsafeOptions、
または ParseHTMLUnsafeOptions
のいずれかである input、
boolean throwIfMissing、文字列 sink、および任意の boolean
optionsFromAuthor(デフォルトは true)が与えられたとき:
-
input が
TrustedHTMLParserOptionsのインスタンスなら、input を返す。 -
requireTrustedTypes を、global、
"script"、および true を渡して シンク型は Trusted Types を必要とするか? アルゴリズムを実行した結果とする。 -
requireTrustedTypes が
falseなら、input を返す。 -
requirePolicy を throwIfMissing とする。
-
optionsFromAuthor が true であり、input が 審査を必要とするなら、 requirePolicy を true に設定する。
注記:
TrustedHTMLとして審査済みのマークアップでも、未審査のサニタイザー(例えばreplaceWithChildrenElementsを使用するもの)を用いて解析したり、スクリプト実行を有効にしたりすると安全でなくなる可能性がある。 このようなオプションはTrustedHTMLParserOptionsまたはデフォルトポリシーのcreateParserOptionsから取得する必要がある。 -
defaultPolicy を、global の Trusted Type ポリシーファクトリーの デフォルトポリシーの値とする。
-
defaultPolicy が null なら:
-
requirePolicy が true なら:
-
disposition を、global、sink、
"script"、および 空文字列を source として渡して シンク型不一致違反を コンテンツセキュリティポリシーによってブロックすべきか? アルゴリズムを実行した結果とする。 -
disposition が
“Allowed”なら、input を返す。 -
TypeErrorをスローする。
-
-
input を返す。
-
-
function を defaultPolicy の オプション["createParserOptions"] とする。
-
function が null なら:
-
requirePolicy が true なら:
-
disposition を、global、sink、
"script"、および 空文字列を source として渡して シンク型不一致違反を コンテンツセキュリティポリシーによってブロックすべきか? アルゴリズムを実行した結果とする。 -
disposition が
“Allowed”なら、input を返す。 -
TypeErrorをスローする。
-
-
input を返す。
-
-
argument を、global の 関連する Realmおよび input が与えられたときに パーサーオプションコールバック 引数を作成する結果とする。
-
policyValue を、function を « argument, "TrustedHTMLParserOptions", sink » および
"rethrow"とともに 呼び出した結果とする。 -
アルゴリズムがエラーをスローした場合、そのエラーを再スローし、以降の手順を中止する。
-
policyValue が
nullまたはundefinedなら:-
disposition を、global、sink、
"script"、および 空文字列を source として渡して シンク型不一致違反を コンテンツセキュリティポリシーによってブロックすべきか?アルゴリズムを実行した結果とする。 -
disposition が
“Allowed”なら、input を返す。注記: この手順により、デフォルト ポリシーによる拒否は報告されるが、report-only モードでは無視されることが保証される。
-
TypeErrorをスローする。
-
-
runScripts を policyValue["runScripts"] の、デフォルトを false とした値とする。
注記: デフォルトポリシーとして呼び出された場合、
createParserOptionsコールバックが最終的なスクリプト実行の挙動を決定し、呼び出し元が要求したrunScriptsオプションを上書きする。 -
global の 関連する Realmで、新しい
TrustedHTMLParserOptionsを返し、その サニタイザー設定は、 global の 関連する Realmおよび policyValue から サニタイザー設定を取得する結果に 設定され、 その runScripts は runScripts に設定される。
SetHTMLUnsafeOptions
または ParseHTMLUnsafeOptions
options は、options["runScripts"] が 存在して true であるか、または
options["sanitizer"] が 存在し、空の SanitizerConfig
でない場合、
審査を必要とする。
注記: 空の SanitizerConfig
は解析されたマークアップを変更しない。
パーサーオプションコールバック引数を作成するには、 Realm realm および辞書 dictionary が与えられたとき:
-
runScriptsInput を dictionary["runScripts"] の、デフォルトを false とした値とする。
-
argument を 有順マップ «[ "runScripts" → runScriptsInput ]» とする。
-
sanitizerInput を、realm および dictionary から サニタイザーを 取得する結果とする。
-
sanitizerInput が null でないなら、argument["sanitizer"] を sanitizerInput に設定する。
-
argument を返す。
辞書から サニタイザーを取得するには、Realm realm および辞書 dictionary が与えられたとき:
-
sanitizerInput を dictionary["sanitizer"] の、null を デフォルト値 とした値とする。
-
sanitizerInput が null なら、null を返す。
-
configuration を null とする。
-
sanitizerInput が
SanitizerPresetsなら:-
表明: sanitizerInput は
"default"である。 -
configuration を 組み込みの安全なデフォルト 設定に設定する。
-
-
そうでなく、sanitizerInput が
Sanitizerなら:-
configuration を sanitizerInput の 設定に設定する。
-
-
そうでなく、sanitizerInput が
SanitizerConfigなら:-
configuration を sanitizerInput に設定する。
-
-
表明: configuration は null ではない。
-
sanitizer を、realm 内の新しい
Sanitizerとする。 -
configuration と true を指定して sanitizer を 設定する。
-
sanitizer を返す。
辞書からサニタイザー設定のコピーを取得するには、 Realm realm および辞書 dictionary が与えられたとき:
-
sanitizer を、realm および dictionary から サニタイザーを 取得する結果とする。
-
sanitizer が null なら、null を返す。
-
sanitizer の 設定を返す。
3.7. デフォルトポリシーで値を処理する
このアルゴリズムは、インジェクションシンクへ代入される値を、存在する場合にはデフォルトポリシーを通して処理する。
デフォルトポリシーで値を処理するには、TrustedType
型 (expectedType)、グローバルオブジェクト (global)、
TrustedType
または文字列 (input)、および文字列 (sink) が与えられたとき、次の手順を実行する:
-
defaultPolicy を、global の Trusted Type ポリシーファクトリーの デフォルトポリシーの値とする。
-
policyValue を、次の引数で Trusted Type ポリシー値を取得するを実行した結果とする:
-
policy として defaultPolicy
-
value として文字列化した input
-
trustedTypeName として expectedType の型名
-
arguments として « trustedTypeName, sink »
-
throwIfMissing として false
-
-
アルゴリズムがエラーをスローした場合、そのエラーを再スローし、以降の手順を中止する。
-
policyValue が null または undefined なら、policyValue を返す。
-
dataString を policyValue を文字列化した結果とする。
-
型名が trustedTypeName であり、関連付けられたデータ値を dataString に設定したインターフェイスの新しいインスタンスを返す。
3.8. スクリプトテキストを準備する
スクリプト
テキストを準備するには、HTMLScriptElement
または SVGScriptElement
(script) が与えられたとき、次の手順を実行する:
-
script が
HTMLScriptElementなら、 sink を "HTMLScriptElement text" とし、 そうでなければ "SVGScriptElement text" とする。 -
script の スクリプトテキスト値が、その 子テキスト内容と等しくない場合、 script の スクリプトテキストを、次の引数で Trusted Type 準拠の文字列を取得するを実行した 結果に設定する:
-
expectedType として
TrustedScriptURL、 -
global として script の
Documentの 関連するグローバルオブジェクト、 -
input として script の 子テキスト内容属性値、
-
sink、
-
sinkGroup として
'script'。
アルゴリズムがエラーをスローした場合、そのエラーを再スローする。
-
3.9. Trusted Type 準拠の属性値を取得する
Trusted Type 準拠の属性値を取得するには、
文字列 attributeName、文字列 attributeNs、Element
element、および TrustedType
または文字列 newValue が与えられたとき、次の手順を実行する:
-
attributeNs が空文字列なら、attributeNs を null に設定する。
-
attributeData を、次の引数で 属性の Trusted Type データを取得する アルゴリズムを実行した結果に設定する:
-
element
-
attributeName
-
attributeNs
-
-
attributeData が null なら:
-
newValue が文字列なら、newValue を返す。
-
表明: newValue は
TrustedHTMLまたはTrustedScriptまたはTrustedScriptURLである。 -
value に関連付けられたデータを返す。
-
-
expectedType を attributeData の第4メンバーの値とする。
-
sink を attributeData の第5メンバーの値とする。
-
次の引数で Trusted Type 準拠の文字列を取得するを実行した 結果を返す:
-
expectedType
-
input として newValue
-
global として element の ノード文書の 関連するグローバルオブジェクト
-
sink
-
sinkGroup として 'script'
-
アルゴリズムがエラーをスローした場合、そのエラーを再スローする。
3.10. 属性の Trusted Type データを取得する
属性の Trusted Type データを取得するには、element、attribute、 attributeNs が与えられたとき、次の手順を実行する:
以下で使用されている イベントハンドラー内容属性という概念は 曖昧である。この仕様にはイベントハンドラー属性を識別するためのより良い仕組みが必要である。https://github.com/w3c/trusted-types/issues/520を参照。
-
data を null とする。
-
attributeNs が null で、« HTML 名前空間、SVG 名前空間、MathML 名前空間 » が element の 名前空間を 含み、attribute が イベントハンドラー内容属性の名前なら:
-
(
Element、 null、attribute、TrustedScript、 "Element " + attribute) を返す。
-
-
次の表から、element が第1列、 attributeNs が第2列、 attribute が第3列にある行を探す。 一致する行が見つかった場合、data をその行に設定する。
要素 属性の名前空間 属性のローカル名 TrustedType シンク HTMLIFrameElementnull "srcdoc" TrustedHTML"HTMLIFrameElement srcdoc" HTMLScriptElementnull "src" TrustedScriptURL"HTMLScriptElement src" SVGScriptElementnull "href" TrustedScriptURL"SVGScriptElement href" SVGScriptElementXLink 名前空間 "href" TrustedScriptURL"SVGScriptElement href" -
data を返す。
4. 統合
typedef (TrustedHTML or TrustedScript or TrustedScriptURL );TrustedType
4.1. HTML との統合
Window
および Worker
オブジェクトには、Trusted Type ポリシーファクトリーがあり、
これは TrustedTypePolicyFactory
オブジェクトである。
4.1.1. WindowOrWorkerGlobalScope の インターフェイス拡張
この文書は、HTMLで定義された WindowOrWorkerGlobalScope
インターフェイスを次のように拡張する:
partial interface mixin WindowOrWorkerGlobalScope {readonly attribute TrustedTypePolicyFactory ; };trustedTypes
trustedTypes
getter の手順は、this
の 関連するグローバルオブジェクトの Trusted
Type ポリシーファクトリーを返すことである。
4.1.2. スクリプトに対する強制
この文書は、HTMLScriptElement
の
子テキスト内容を設定する方法を変更し、アプリケーションが
動的に作成されたスクリプトを制御できるようにする。これは、
innerText
および textContent
属性を HTMLScriptElement
に直接追加することで実現する。
属性の挙動は、
Trusted Type
準拠の文字列を取得するを呼び出す追加の挙動を除き、元の対応する属性と同じままである。
注記: これらの IDL 属性を使用することが、 スクリプトの URL またはテキストを動的に設定する推奨方法である。属性ノードやテキストノードを直接操作すると、 スクリプトの準備時に最終値に対してデフォルトポリシーが呼び出される。
partial interface HTMLScriptElement { [CEReactions ]attribute (TrustedScript or [LegacyNullToEmptyString ]DOMString ); [innerText CEReactions ]attribute (TrustedScript or DOMString )?; [textContent CEReactions ]attribute (TrustedScriptURL or USVString ); [src CEReactions ]attribute (TrustedScript or DOMString ); };text
4.1.2.1. 信頼された値を持つスロット
HTMLScriptElement
および SVGScriptElement
には次のものがある:
- 関連付けられた文字列 スクリプトテキスト。
-
準拠したシンクを通じて設定された、実行するスクリプト本体を含む文字列。 スクリプトの 子テキスト内容と等価である。初期状態では空文字列である。
4.1.2.2.
innerText
IDL 属性
innerText
setter の手順は次のとおり:
-
value を、
TrustedScript、 this の 関連するグローバルオブジェクト、指定された値、HTMLScriptElement innerText、およびscriptを使用して Trusted Type 準拠の文字列を取得するを呼び出した結果とする。 -
this および value を使用して 内部テキストを設定する手順を実行する。
innerText
getter の手順は次のとおり:
-
this を使用して テキストを 取得する手順を実行した結果を返す。
4.1.2.3.
textContent
IDL 属性
textContent
setter の手順は、指定された値が null なら代わりに
空文字列であるかのように扱い、その後、次に記述するように処理する:
-
value を、
TrustedScript、 this の 関連するグローバルオブジェクト、指定された値、HTMLScriptElement textContent、およびscriptを使用して Trusted Type 準拠の文字列を取得するを呼び出した結果とする。 -
this および value を使用して テキスト内容を設定するを実行する。
textContent
getter の手順は次のとおり:
-
this を使用して テキスト 内容を取得するを実行した結果を返す。
注記: 現在、SVGScriptElement
に対応するものは追加していない。
https://github.com/w3c/trusted-types/issues/512を参照。
4.1.2.4.
text
IDL 属性
text
setter の手順アルゴリズムを次のように更新する。
-
value を、
TrustedScript、 this の 関連するグローバルオブジェクト、指定された値、HTMLScriptElement text、およびscriptを使用して Trusted Type 準拠の文字列を取得するを呼び出した結果とする。 - this の スクリプトテキスト値を指定された値に設定する。
-
this 内で指定された値を使用して 文字列をすべて置換する。
4.1.2.5.
src
IDL 属性
src
getter の手順は次のとおり:
- element を、this の要素を取得する処理を 実行した結果とする。
- contentAttributeValue を、this の内容 属性を取得する処理を実行した結果とする。
- contentAttributeValue が null なら、空文字列を返す。
- urlString を、element の ノード文書を基準として、 contentAttributeValue を指定して URL をエンコーディング解析しシリアライズした結果とする。
- urlString が失敗でないなら、urlString を返す。
- スカラー値文字列に変換した contentAttributeValue を返す。
src
setter の手順は次のとおり:
-
value を、
TrustedScriptURL、 this の 関連するグローバルオブジェクト、指定された値、HTMLScriptElement src、およびscriptを使用して Trusted Type 準拠の文字列を取得するを呼び出した結果とする。 - this の src 内容属性を value に設定する。
4.1.2.6. パーサーからのスロット値の設定
この文書は、スクリプトの作成時に スクリプトテキスト値を設定するよう HTML パーサーを変更する。
テキスト挿入モードアルゴリズムを次のように変更する:
- タグ名が "script" である終了タグ
-
...
script の スクリプトテキスト値を、その 子テキスト内容に設定する。
アクティブな投機的 HTML パーサーが null なら、script をスクリプト 要素を準備する。これにより一部のスクリプトが実行され、その結果 新しい文字がトークナイザーに挿入される可能性があり、 トークナイザーがさらに多くのトークンを出力し、パーサーの再入可能な 呼び出しが発生する可能性がある。
...
上記のアルゴリズムは、 解析途中で script 要素の内容が変更される場合を考慮していない。実装者は この場合から確実に保護しなければならない。https://github.com/w3c/trusted-types/issues/507を参照。
SVG script 要素の処理には
適切な定義がない。しかし、実装は SVGScriptElement
の処理に
同様の変更を適用しなければならない。
4.1.2.7. スロット値の検証
スクリプト要素を準備するアルゴリズムの最初のいくつかの手順を 次のように変更する:
-
el の すでに開始済みが true なら、返る。
-
parser document を el の パーサー文書とする。
-
el の パーサー文書を null に設定する。
これは、パーサーによって挿入された
script要素が、例えば空であるか、サポートされていない スクリプト言語を指定しているために、パーサーが実行しようとしたときに実行に失敗した場合でも、 後で別のスクリプトがそれらを変更して再び実行させられるようにするためである。 -
parser document が非 null であり、el が
async属性を持たない場合、el の 強制 asyncを true に設定する。これは、パーサーによって挿入された
script要素がパーサーによって実行されるときに 実行に失敗しても、後でスクリプトによって動的に 更新された後に実行される場合、async属性が設定されていなくても非同期方式で実行されるようにするためである。 -
el に対して スクリプトテキストを準備するアルゴリズムを実行する。 そのアルゴリズムがエラーをスローした場合、返る。
- ...
SVG script 要素の処理には
適切な定義がない。しかし、実装は SVGScriptElement
の処理に
同様の変更を適用しなければならない。
4.2. コンテンツセキュリティポリシーとの統合
4.2.1. require-trusted-types-for ディレクティブ
この文書は、require-trusted-types-for、すなわち新しい コンテンツセキュリティポリシー ディレクティブを定義する。
require-trusted-types-for ディレクティブは、現在の Realm における特定のグループのすべての インジェクションシンクについて Trusted Types フレームワークを設定する。 具体的には、指定されたグループの インジェクションシンクに 文字列値が渡されたときの挙動(すなわち、そのようなシンクに対して型ベースの強制を有効にすべきか)を定義する。
注記: 現在、§ 2.1.1 DOM XSS インジェクションシンクに対する強制のみが指定されている。
ディレクティブの 名前および 値の構文は、 次の ABNF によって記述される:
directive-name = "require-trusted-types-for" directive-value = trusted-types-sink-group-keyword *( required-ascii-whitespace trusted-types-sink-group-keyword) trusted-types-sink-group-keyword = "'" trusted-types-sink-group "'" trusted-types-sink-group = "script"
Content-Security-Policy: require-trusted-types-for 'script'
4.2.1.1. require-trusted-types-for
ナビゲーション前チェック
リクエスト (request)、文字列 navigation type、および
ポリシー (policy) が与えられたとき、このアルゴリズムは、
ナビゲーションが require-trusted-types-for ディレクティブの制約に違反する場合
"Blocked" を返し、
そうでなければ "Allowed" を返す。これは require-trusted-types-for ディレクティブの ナビゲーション前チェックを構成する:
注記: このアルゴリズムは、
javascript: URL へのナビゲーションによって実行されるコードが、他の
CSP ディレクティブによって課されるすべての制限に加えて、デフォルト
ポリシーの createScript 関数を通過しなければならないことを保証する。
-
request の URL の スキームが
"javascript"でないなら、"Allowed"を返し、以降の手順を中止する。 -
urlString を、request の URL に対して URL シリアライザーを実行した結果とする。
-
encodedScriptSource を、urlString から先頭の
"javascript:"を 削除した結果とする。 -
convertedScriptSource を、次の引数で デフォルトポリシーで値を処理する アルゴリズムを実行した結果とする:
-
expectedType として
TrustedScript -
global として request の クライアントの グローバルオブジェクト
-
input として encodedScriptSource
-
sink として
"Location href"
そのアルゴリズムがエラーをスローしたか、convertedScriptSource が
TrustedScriptオブジェクトでない場合、"Blocked" を返し、以降の手順を中止する。 -
-
urlString を、文字列化した convertedScriptSource の先頭に
"javascript:"を付加した結果に設定する。 -
newURL を、urlString に対して URL パーサーを実行した結果とする。パーサーが失敗を返す場合、
"Blocked"を返し、以降の手順を中止する。 -
request の URL を newURL に設定する。
注記: ナビゲーション前チェックでは、
javascript:URL に対して動作する他の CSP ディレクティブはない。javascript: URL を検査するその他のディレクティブは、後で変更後の URL に対して インラインチェック内で動作する。 -
"Allowed"を返す。
4.2.2. trusted-types ディレクティブ
この文書は、trusted-types、すなわち新しい コンテンツセキュリティポリシー ディレクティブを定義する。trusted-types ディレクティブは Trusted Type ポリシーの作成を制御する。
ディレクティブの 名前および 値の構文は、 次の ABNF によって記述される:
directive-name = "trusted-types" directive-value = serialized-tt-configuration serialized-tt-configuration = ( tt-expression *( required-ascii-whitespace tt-expression ) ) tt-expression = tt-policy-name / tt-keyword / tt-wildcard tt-wildcard = "*" tt-policy-name = 1*( ALPHA / DIGIT / "-" / "#" / "=" / "_" / "/" / "@" / "." / "%") tt-keyword = "'allow-duplicates'" / "'none'"
Content-Security-Policy: require-trusted-types-for 'script'; trusted-types one two
Content-Security-Policy: trusted-types; require-trusted-types-for 'script'
キーワード 'none' を使用して、上記を明示的に表現できる:
キーワード 'allow-duplicates' は、すでに使用された名前でポリシーを作成できるようにする。
default という名前のポリシーが一覧に存在する場合、それは デフォルトポリシーを指す。
インジェクション
シンクに渡されるすべての文字列は、即座に拒否される代わりに、そのポリシーを通して処理される。
4.2.3. シンク型は Trusted Types を必要とするか?
インジェクションシンクが Trusted Type を必要とする場合、このアルゴリズムは
true を返し、
そうでなければ false を返す。
シンク型は Trusted Types を必要とするか?アルゴリズムは、グローバルオブジェクト (global)、文字列 (sinkGroup) および boolean (includeReportOnlyPolicies) が与えられたとき、次の手順を実行する:
-
global の CSP リスト内の各 policy について:
-
policy の ディレクティブ集合に、 ディレクティブで、その 名前が
"require-trusted-types-for"であるものが 含まれていない場合、次の policy へ進む。 -
directive を、policy の directive set において 名前が
"require-trusted-types-for"である ディレクティブとする。 -
directive の 値に、sinkGroup と一致する trusted-types-sink-group が 含まれていない場合、次の policy へ進む。
-
policy の 処置が
"enforce"なら enforced を true とし、そうでなければ false とする。 -
enforced が true なら、true を返す。
-
includeReportOnlyPolicies が true なら、true を返す。
-
-
false を返す。
4.2.4. シンク型不一致違反をコンテンツセキュリティ ポリシーによってブロックすべきか?
インジェクションシンクが Trusted Type を必要とする場合、このアルゴリズムは
"Blocked" を返し、
そうでなければ "Allowed" を返す。
シンク型不一致 違反をコンテンツセキュリティポリシーによってブロックすべきか?アルゴリズムは、グローバルオブジェクト (global)、文字列 (sink)、 文字列 (sinkGroup) および文字列 (source) が与えられたとき、次の手順を実行する:
-
result を
"Allowed"とする。 -
sample を source とする。
-
sink が
"Function"なら:-
sample が
"function anonymous"で始まるなら、それを sample から取り除く。 -
そうでなく、sample が
"async function anonymous"で始まるなら、それを sample から取り除く。 -
そうでなく、sample が
"function* anonymous"で始まるなら、それを sample から取り除く。 -
そうでなく、sample が
"async function* anonymous"で始まるなら、それを sample から取り除く。
-
-
global の CSP リスト内の各 policy について:
-
policy の ディレクティブ集合に、 ディレクティブで、その 名前が
"require-trusted-types-for"であるものが 含まれていない場合、次の policy へ進む。 -
directive を、policy の directive set において 名前が
"require-trusted-types-for"である ディレクティブとする。 -
directive の 値に、sinkGroup と一致する trusted-types-sink-group が 含まれていない場合、次の policy へ進む。
-
violation を、 global、policy および
"require-trusted-types-for"に対して グローバル、ポリシー、および ディレクティブの違反オブジェクトを作成するを実行した結果とする。 -
violation の リソースを
"trusted-types-sink"に設定する。 -
trimmedSample を、sample の先頭40 文字を含む部分文字列とする。
-
violation の サンプルを、区切り文字として
"|"を使用して リスト « sink, trimmedSample « を 連結した結果に設定する。 -
violation に対して 違反を報告するを実行する。
-
policy の 処置が
"enforce"なら、result を"Blocked"に設定する。
-
-
result を返す。
4.2.5. Trusted Type ポリシーの作成をコンテンツセキュリティ ポリシーによってブロックすべきか?
TrustedTypePolicy
を作成すべきでない場合、このアルゴリズムは "Blocked" を返し、そうでなければ "Allowed" を返す。
Trusted Type ポリシーの作成をコンテンツセキュリティポリシーによってブロックすべきか?アルゴリズムは、グローバルオブジェクト (global)、文字列 (policyName)、および 文字列のリスト (createdPolicyNames) が与えられたとき、次の手順を実行する:
-
result を
"Allowed"とする。 -
global の CSP リスト内の各 policy について:
-
createViolation を false とする。
-
policy の ディレクティブ集合に、 ディレクティブで、 その名前が
"trusted-types"であるものが含まれていない場合、次の policy へ進む。 -
directive を、policy の directive set において 名前が
"trusted-types"である ディレクティブとする。 -
directive の 値に、値
'none'と一致する tt-keywordだけが 含まれる場合、createViolation を true に設定する。注記: 他の CSP ディレクティブと同様に、 他のキーワードまたはポリシー名が存在する場合、'none' キーワードは無視される。
-
createdPolicyNames に policyName が含まれ、かつ directive の 値に、値
'allow-duplicates'と一致する tt-keyword が 含まれていない場合、createViolation を true に設定する。注記:
trusted-types policyA policyB 'allow-duplicates'により、作者は 重複する名前の ポリシーを作成できる。 -
directive の 値に、値が policyName である tt-policy-name が含まれず、 かつ directive の 値に tt-wildcard が含まれない場合、 createViolation を true に設定する。
注記:
trusted-types *により、作者は任意の一意な名前でポリシーを作成できる。同じ名前の複数のポリシーを許可するには、trusted-types * 'allow-duplicates'を使用するか、trusted-typesディレクティブをまったく設定しない。 -
createViolation が false なら、次の policy へ進む。
-
violation を、 global、policy および
"trusted-types"に対して グローバル、ポリシー、およびディレクティブの 違反オブジェクトを作成するを実行した結果とする。 -
violation の リソースを
"trusted-types-policy"に設定する。 -
violation の サンプルを、policyName の 先頭40文字を含む部分文字列に設定する。
-
violation に対して 違反を報告するを実行する。
-
policy の 処置が
"enforce"なら、result を"Blocked"に設定する。
-
-
result を返す。
5. セキュリティに関する考慮事項
Trusted Types は、積極的に悪意ある実行環境において インジェクションシンクへのアクセスを保護することを意図していない。 アプリケーションは悪意のない作者によって 記述されていることを前提とする。その目的は、セキュリティ上のバグにつながり得る 開発者のミスを防止することであり、ポリシーの制限を積極的に回避しようとする ファーストパーティの悪意あるコードから防御することではない。以下では、 Trusted Types が強制される環境でもなお危険であると すでに特定されているベクトルを列挙する。
5.1. 文書間ベクトル
Trusted Types が強制されているウィンドウで実行されるコードは、
ポリシーの制限を回避するノードを動的に作成できないが、
同じ制限の集合を持たない別のウィンドウの
文書から、そのようなノードをインポートまたは採用できる可能性がある。本質的には、
悪意ある作者が、制限された文書と制限されていない文書が
結託する構成を作成すれば、Trusted Types を回避できる。極端な場合、
制限された文書が文字列から Blob
を作成し、そこへナビゲートする可能性がある。
CSP の伝播規則(コンテンツセキュリティ
ポリシー 3 § 7.8 回避を防ぐための CSP の継承を参照)は、この
問題に部分的に対処する。新しい ローカルスキーム文書は同じ制限の集合を継承するため、
例えば script-src の制限を使用して、
Blob
の内容へのインジェクションによってスクリプトが実行されないようにできる。この問題に
包括的に対処するには、Origin Policy のような他の仕組みを
使用して、基準となるセキュリティ規則がオリジン全体に
適用されるようにすべきである。
5.2. 非推奨の機能
長い間非推奨であり、ほとんど使用されていない一部のプラットフォーム機能は Trusted Types の対象ではなく、悪意ある作者が 制限を回避するために使用できる可能性がある:
5.3. スクリプトガジェット
Trusted Types のロジックは、文字列から DOM ツリーを作成する結果となる多くの操作で呼び出されるが、文書内の あらゆる DOM ツリー作成を保護する仕組みとして扱うべきではない。これは特に、 スクリプトガジェットが存在する場合に重要である。 そこでは、アプリケーションが通常は無害な DOM 要素や属性の内容に反応する。 DOM API を直接使用する開発者は、 Trusted Types を使用せずにこのようなガジェットを起動できる。しかし、ガジェットが DOM XSS を引き起こすには、 ポリシーを介して Trusted Type 値を取得する必要がある。ポリシーの規則自体が 制約を強制したりデータを検証したりしない場合、作者は Trusted Type ポリシーに 渡されるデータが実際に信頼できることを確認する必要がある。
5.4. ポリシー設計のベストプラクティス
Trusted Types は、インジェクション シンクを介して脆弱性を導入できるコードの範囲を、ポリシーの実装に限定する。 この設計でも、安全でないポリシーは インジェクションシンクを信頼できないデータにさらす可能性がある。 あらゆる入力に対して安全なポリシーを使用するか、安全でないポリシーへのアクセスを制限して、 攻撃者に制御されていない入力でのみ 呼び出されるようにすることに、特に注意を払う必要がある。
ポリシーは独自の JavaScript コードであるため、グローバル状態に 大きく依存するように記述される可能性がある。これは推奨しない。ポリシーは 可能な限り自己完結すべきである。ポリシーが行うセキュリティ判断を変更し得るすべてのオブジェクトは 実質的にそのポリシーの一部になるため、 一緒に保護し、レビューすべきである。
createParserOptions
コールバックが、安全でないマークアップ(例えばスクリプトやイベントハンドラー)を除去しない設定を返す場合、
DOM XSS に対する保護は提供されない。
ポリシー作者は、createParserOptionsに渡される
argument["sanitizer"] 内の呼び出し元提供のサニタイザーも慎重に検査すべきである。
呼び出し元のサニタイザーを盲目的に信頼したり、そのまま渡したりすると、未審査の設定が解析を支配できてしまう。
createParserOptions
は入力マークアップが既存の TrustedHTML
インスタンスである場合でも実行されるため、
デフォルトポリシーにより、未審査の呼び出し元オプションがアプリケーション全体のサニタイズや
スクリプト実行の制約を回避できないことが保証される。
このようなコールバックがない場合、TrustedHTML
を、呼び出し元提供の空でないサニタイザーや true に設定された runScripts と組み合わせることはできない。
それらによって審査済みのマークアップが安全でなくなる可能性があるためである。
6. プライバシーに関する考慮事項
この仕様は、アプリケーション内で実行されるスクリプトの挙動を 部分的に観察および変更する場合がある。例えば、インジェクションシンクに対する特定の操作を 失敗させたり、デフォルトポリシーを使用して その影響を監視および変更したりする。 ただし、早期に実行されるスクリプトは、適切なプロパティディスクリプターを 上書きすることで、すでにこの能力を持っている。
アプリケーションは Trusted Types の 制限への違反を報告できる。違反レポートには、 インジェクションシンクに渡された切り詰められたペイロード(シンク名を含む40文字)が含まれる。この機能は コンテンツセキュリティポリシーの報告機構を再利用する。
7. 実装に関する考慮事項
7.1. ベンダー固有の拡張機能とアドオン
Trusted Types によって課される制限は、 アドオン、拡張機能、ブックマークレットなどのユーザーエージェント機能の動作を 妨げるべきではない。これらの種類の機能は一般に、 [html-design-principles]で提唱されているように、 ページ作者よりもユーザーの優先権を高める。具体的には、拡張機能は インジェクションシンクへ 文字列を渡せるべきであり、 デフォルトポリシーの 実行、違反の生成、または値の拒否を引き起こすべきではない。