結論(Trusted Typesの適用)
Trusted Typesの適用とは、CSPに require-trusted-types-for 'script' を指定し、危険なAPIにただの文字列を渡すことをブラウザに禁止させることです。対象は innerHTML・outerHTML・insertAdjacentHTML・document.write・eval などの、DOM XSSの原因になるAPI(インジェクションシンク)です。シンクにはポリシー関数で検査・無害化した TrustedHTML などのオブジェクトしか渡せなくなり、文字列を渡すと TypeError になります。
この記事のポイント
- Trusted Typesは、CSPの require-trusted-types-for 'script' で強制し、trusted-types で作成できるポリシー名を制限します。
- MDNによれば2026年2月にBaseline(Newly available)となり、Chrome/Edgeに加えSafariとFirefoxでも利用できます。
- サーバー側で生成される反射型・格納型XSSは対象外で、シンクの使い方の修正の代替にはなりません。
- セキュリティAIチェッカーは強制CSPに require-trusted-types-for 'script' があれば○、未適用でHTML内にシンクの兆候があれば△(重み1の参考項目)です。
- Report-Onlyで違反箇所を洗い出し、textContent等への置き換えとサニタイズ用ポリシーの導入を経て強制するのが安全な手順です。
| 診断項目名 | Trusted Typesの適用 |
|---|---|
| 項目ID | headers.trusted-types |
| 分類 | コンテンツセキュリティポリシー(CSP) |
| 重大度・配点の重み | 低(low) 重み 1 |
| 関連する標準・ガイドライン | OWASP WSTG-CONF-12(Review Trusted Types Interaction)、WSTG-CLNT-01(DOM-based XSS)、OWASP ASVS 5.0.0 V3.2.2(Level 1、テキスト表示には textContent など安全な描画関数を使う)、V3.4.3(Level 2、CSP)、W3C Trusted Types(CSP の require-trusted-types-for/trusted-types ディレクティブ)、IPA「安全なウェブサイトの作り方」1.5 クロスサイト・スクリプティング、CWE-79(XSS) |
Trusted Typesの適用とは
Trusted Typesの適用とは、Content Security Policy(CSP)に require-trusted-types-for 'script' を指定して、DOM XSSの原因となる危険なAPIに、ただの文字列を渡すことをブラウザに禁止させることです。
対象となる危険なAPIは「インジェクションシンク」と呼ばれ、次のようなものがあります。
innerHTML、outerHTML、insertAdjacentHTMLdocument.writeeval、setTimeoutへの文字列渡しscript.srcなど
CSPに require-trusted-types-for 'script' を指定すると、これらのシンクには、ポリシー関数で検査・無害化した TrustedHTML/TrustedScript/TrustedScriptURL オブジェクトしか渡せなくなり、文字列を渡すと TypeError になります。
Trusted Typesの対応状況と位置づけ
MDNによれば、Trusted Types は2026年2月に Baseline(Newly available)となり、Chrome/Edge に加えて Safari と Firefox でも利用できるようになりました。ただし、既存のJavaScriptライブラリが文字列でシンクを使っていることが多く、導入には段階的な改修が必要です。このためセキュリティAIチェッカーでは、参考項目(low、重み1)として扱います。
Trusted Typesの仕組みとポリシーの書き方
2つのディレクティブ
| ディレクティブ | 役割 |
|---|---|
require-trusted-types-for 'script' | シンクへの文字列代入を禁止する(強制の本体) |
trusted-types ポリシー名 ... | trustedTypes.createPolicy() で作れるポリシー名を許可リストで制限する。'allow-duplicates' を付けない限り、同名ポリシーの重複作成も禁止される |
OWASP WSTG-CONF-12 は、次の点を確認するよう求めています。
trusted-typesだけでrequire-trusted-types-forがなければ強制されないことtrusted-types *や、何でも通す default ポリシーは保護を無効化すること
ポリシーの例
// DOMPurify でサニタイズしてから TrustedHTML にする
const policy = trustedTypes.createPolicy("sanitize", {
createHTML: (input) => DOMPurify.sanitize(input),
});
element.innerHTML = policy.createHTML(userInput);
default という名前のポリシーを作ると、文字列がシンクに渡されたときに自動で呼ばれます。MDNはこれを既存コード改修中の移行手段として位置づけており、恒久的な解決策ではありません。
Trusted Typesについてよくある誤解
- 「Trusted Typesを入れればXSS対策は完了」:そうではありません。サーバー側テンプレートで生成される反射型・格納型XSS(HTMLインジェクション)は対象外です。WSTGも、根本原因(シンクの使い方)の修正の代替ではないとしています。
- 「innerHTMLを使っていれば必ず脆弱」:これも誤りです。固定文字列や、適切にエスケープした値だけを入れるなら直ちに危険ではありません。Trusted Typesは、それを機械的に保証する手段です。
- 「導入すると非対応ブラウザで表示が壊れる」:非対応ブラウザでは単に無視されるため、表示が壊れることはありません(対応ブラウザで違反があった場合に壊れます)。
JavaScript内の危険なAPIの使用状況そのものは「危険なJavaScript APIの兆候」でも確認します。
Trusted Typesの適用の診断基準(セキュリティAIチェッカー)
取得方法
トップページの最終応答1件について、次の2点を確認します。追加の通信はありません。
- 強制
Content-Security-Policyレスポンスヘッダーにrequire-trusted-types-for 'script'があるか。ヘッダーが複数ある(カンマ連結)場合も、いずれかのポリシーにあれば適用ありとします。大文字小文字は区別しません。 - 取得したHTML本文(インラインscriptを含む)に、
innerHTML、outerHTML、insertAdjacentHTML、document.write、eval((evalと(の間の空白は許容)のいずれかの文字列があるか(DOM XSSシンクの兆候)。大文字小文字を区別しない単純な文字列一致で、eval(だけは語の先頭から始まる場合に限ります(window.eval(は一致し、retrieval(や_eval(は一致しません)。外部JavaScriptファイルの中身は取得しません。
判定条件
| 判定 | 条件 | 根拠文の例 |
|---|---|---|
| ○ 問題なし(pass) | require-trusted-types-for 'script' あり | require-trusted-types-for 'script'を確認 |
| △ 要確認(warn) | 未適用、かつHTML内にシンクの兆候あり | DOM/XSSシンクの兆候があるがTrusted Typesは未適用 |
| 対象外(na) | 未適用、かつシンクの兆候なし | 対象シンクの兆候がないため参考項目 |
- Report-Onlyヘッダーやmeta要素の
require-trusted-types-forは、強制とみなしません。 trusted-typesディレクティブの許可ポリシー名の妥当性(*や緩い default ポリシー)は評価しません。
得点への影響
| 判定 | 得点 |
|---|---|
| ○ 問題なし(pass) | 1点(重み1) |
| △ 要確認(warn) | 0.45点 |
| 対象外(na) | 採点から除外 |
総合スコアへの影響は小さく、主に改善の方向性を示すための項目です。
自治体サイトでの判定例
| 状況 | 判定 |
|---|---|
CMSが出力するトップページに、アクセス解析タグの document.write が残っている | △ |
| jQuery 等の外部ファイルだけを読み込み、HTML本文にシンク文字列がない | 対象外(外部JS内のシンクは見ていないため) |
電子申請システムで require-trusted-types-for 'script' を強制している | ○ |
HTML内のコメントや説明文に「innerHTML」という単語があるだけでも兆候として数えるため、△の結果は目視で確認してください。retrieval( のように eval( を末尾に含む別の関数名は兆候に数えません。
Trusted Typesがないとどんなリスクがあるか(DOM XSS)
- 痕跡が残りにくいDOM XSS:DOM XSSは、URLのフラグメント(
#以降)やクエリ、postMessageの値をJavaScriptが innerHTML 等へ渡すことで発生し、サーバーのログに痕跡が残りにくい特徴があります(WSTG-CLNT-01)。 - 自治体サイト特有の入口:検索結果の表示、多言語切替、ふりがな・読み上げ等の補助ツール、地図やイベントカレンダーの埋め込みなど、クライアント側でHTMLを組み立てる機能が多く、DOM XSSの入口になり得ます。
- 攻撃成立時の被害:偽のログイン画面・申請フォームの表示、入力内容の外部送信、サイト内の情報の改ざん表示が可能になります(CWE-79)。
- 抜け漏れを機械的に防げない:Trusted Typesがない場合でも、他の対策(出力エスケープ、CSPの script-src 制限)で防げることはありますが、シンクごとの抜け漏れを機械的に検出・遮断する手段がありません。
Trusted Typesの導入方法(Apache・nginx・IIS・Next.js)
段階1:Report-Onlyで違反箇所を洗い出す
# Apache(.htaccess)
<IfModule mod_headers.c>
Header always set Content-Security-Policy-Report-Only "require-trusted-types-for 'script'; report-uri /csp-report"
</IfModule>
# nginx
add_header Content-Security-Policy-Report-Only "require-trusted-types-for 'script'; report-uri /csp-report" always;
ブラウザの開発者ツールのコンソールにも違反が表示されます。どのファイルの何行目でシンクに文字列が渡されているかを一覧にします。
段階2:コードを安全なAPIへ置き換える
// 悪い例
el.innerHTML = "<b>" + name + "</b>";
// 良い例(テキストとして表示)
const b = document.createElement("b");
b.textContent = name;
el.replaceChildren(b);
テキスト表示に textContent など安全な描画関数を使うことは、OWASP ASVS 5.0.0 V3.2.2(Level 1)の要件でもあります。HTMLを挿入する必要がある箇所だけ、サニタイズを行うポリシー経由にします。DOMPurify は RETURN_TRUSTED_TYPE: true オプションで TrustedHTML を返せます。
段階3:強制する
Header always set Content-Security-Policy "default-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'self'; require-trusted-types-for 'script'; trusted-types sanitize dompurify"
IIS では web.config の customHeaders、Next.js では next.config.js の headers() または proxy.ts(Next.js 15 以前は middleware.ts)で同じ値を設定します。
// next.config.js
module.exports = {
async headers() {
return [{ source: "/(.*)", headers: [{ key: "Content-Security-Policy",
value: "object-src 'none'; base-uri 'self'; require-trusted-types-for 'script'; trusted-types sanitize" }] }];
},
};
フレームワークやバンドラー(webpack 等)、ライブラリは、独自の名前でポリシーを作ることがあります。trusted-types の許可リストに無い名前は作成時に例外になるため、Report-Only段階でコンソールに出るポリシー名を確認して、許可リストに加えます。
設定後の確認方法
curl -sI https://www.city.example.lg.jp/ | grep -i '^content-security-policy:' | grep -io "require-trusted-types-for[^;,]*"
ブラウザで trustedTypes.createPolicy が使えるか、また開発者ツールに This document requires 'TrustedHTML' assignment のような違反が出ていないかを、主要画面ごとに確認します。
サイトを壊さないための注意点(ガードレール)
- CMSのテンプレート、アクセス解析タグ、広告・翻訳・地図などの外部ウィジェットは、文字列でシンクを使うことが多く、強制すると機能が止まる可能性があります。必ずReport-Onlyの期間を設けてください。
- 何でも通す default ポリシー(入力をそのまま返す)を作ると、強制していても保護効果はほぼなくなります。
- 上位ディレクトリで一括適用すると、配下の全アプリに影響します。対応済みのアプリのディレクトリ単位で導入するのが安全です。
- 本項目は low・重み1の参考項目です。「CSPがレスポンスヘッダーで強制されている」、「CSPの基幹ディレクティブ」、「CSPでunsafe-inlineを許可していない」など、優先度の高い対策を先に行ってください。
よくある質問(FAQ)
Trusted Typesに対応しているブラウザは?
MDNによれば、Trusted Typesは2026年2月にBaseline(Newly available)となり、Chrome/Edgeに加えてSafariとFirefoxでも利用できるようになりました。非対応のブラウザでは単に無視されるため、導入しても表示が壊れることはありません。
Trusted Typesを入れればXSS対策は完了ですか?
完了ではありません。Trusted Typesが防ぐのはJavaScriptがシンクに文字列を渡すことによるDOM XSSで、サーバー側テンプレートで生成される反射型・格納型XSS(HTMLインジェクション)は対象外です。WSTGも根本原因の修正の代替ではないとしています。
require-trusted-types-for と trusted-types の違いは何ですか?
require-trusted-types-for 'script' がシンクへの文字列代入を禁止する強制の本体です。trusted-types は trustedTypes.createPolicy() で作れるポリシー名を許可リストで制限するもので、これだけでは強制されません。
defaultポリシーを作れば既存コードを直さずに済みますか?
defaultという名前のポリシーは文字列がシンクに渡されたときに自動で呼ばれますが、MDNは既存コード改修中の移行手段と位置づけており、恒久的な解決策ではありません。入力をそのまま返すdefaultポリシーでは、強制していても保護効果はほぼなくなります。
innerHTMLを使っていると必ず脆弱ですか?
必ずではありません。固定文字列や適切にエスケープした値だけを入れるなら直ちに危険ではありません。Trusted Typesは、それを機械的に保証する手段です。
HTMLに「innerHTML」という単語があるだけで△になるのはなぜですか?
セキュリティAIチェッカーは、取得したHTML本文に innerHTML などの文字列があるかを大文字小文字を区別しない単純な一致で調べるため、コメントや説明文の単語も兆候に数えます。△の結果は目視で確認してください。外部JavaScriptファイルの中身は取得しません。
Trusted Typesを強制したら外部ウィジェットが動かなくなりました。
アクセス解析タグや広告・翻訳・地図などの外部ウィジェットは、文字列でシンクを使うことが多いためです。Report-Only期間を設けて違反箇所とライブラリが作るポリシー名を確認し、許可リストに加えるか対応済みのアプリのディレクトリ単位で導入してください。
この項目を含む127項目を、URLを入れるだけで無料診断します。
参考資料
- MDN Trusted Types API
- W3C Trusted Types 仕様
- OWASP WSTG-CONF-12 Test for Content Security Policy
- OWASP ASVS 5.0.0 V3 Web Frontend Security(V3.2.2・V3.4.3)
- OWASP DOM based XSS Prevention Cheat Sheet
- web.dev「Prevent DOM-based cross-site scripting vulnerabilities with Trusted Types」
- DOMPurify(GitHub)
- Can I use: Trusted Types
- IPA「安全なウェブサイトの作り方」