0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【セキュリティ】DOM-Based XSS を完全封じるTrusted Types 実践ガイド

0
Posted at

はじめに

— innerHTML があっても怖くない世界へ

XSS の中でも最も防ぎにくいのが DOM-Based XSS
サーバー側のサニタイズが完璧でも、フロントエンドで innerHTMLinsertAdjacentHTML を扱うだけで攻撃者に隙が生まれる。

そんな“フロント側の穴”を塞ぐために Google が提唱した最強の防御が Trusted Types(TT) だ。

Trusted Types の導入により:

  • innerHTML 等の危険操作が すべてブロックされる
  • 開発者は XSS-safe な専用 API 経由でしか HTML を扱えない
  • CSP と組み合わせることで DOM XSS を ほぼ完全封殺 できる

この記事では、Trusted Types の仕組み・導入方法・活用パターンをわかりやすく解説する。


1. DOM-Based XSS の何が危険なのか?

DOM-Based XSS は、次のようなコードが原因で発生する。

element.innerHTML = location.hash;  // 危険!

攻撃者が URL に次のような payload を入れるだけで:

https://example.com/page#<img src=x onerror=alert(1)>

ブラウザ側で 即座に悪意コードが実行される。

サーバーは関係ないため:

  • WAF ではほとんど検出できない
  • バックエンドのサニタイズも無力
  • SPA フレームワークでも発生する

これが DOM XSS が“最後の難関”と言われる理由。


2. Trusted Types とは?(仕組みの核心)

Trusted Types の思想は非常にシンプル:

「innerHTML や document.write に“生の文字列”を入れることを禁止」

→ 安全と証明されたオブジェクト(TrustedHTML)しか受け付けない

これによって、攻撃者が悪意スクリプトを混入する余地がなくなる。


Trusted Types を有効にするには?

CSP に次を追加するだけ:

Content-Security-Policy: require-trusted-types-for 'script';

これでブラウザは:

  • innerHTML
  • outerHTML
  • insertAdjacentHTML
  • document.write
  • setAttribute(on* 系)

などの危険操作に対し、
TrustedHTML 以外を完全拒否する。


3. Trusted Types の実装手順(最短 3 ステップ)

Step 1:CSP で Trusted Types を有効化

例:

Content-Security-Policy:
  require-trusted-types-for 'script';
  trusted-types default;

trusted-types default;
は「default」というポリシー名で実装を受け付ける意味。


Step 2:Trusted Types ポリシーを定義

フロント側 JS に次を追加:

window.trustedTypes.createPolicy("default", {
  createHTML(input) {
    return input; // ここにサニタイズ処理を入れる
  }
});

createHTML() が「安全な HTML を作る唯一の入口」。


Step 3:危険 API を TrustedHTML 経由で使用する

const safe = trustedTypes.getPolicy("default").createHTML(
  sanitize(userInput)
);

element.innerHTML = safe;   // OK(TrustedHTML)

生の文字列を innerHTML に入れるとどうなる?

element.innerHTML = userInput;
// → CSP エラー(XSS 防止成功)

Trusted Types が完全に XSS を遮断してくれる。


4. Trusted Types の効果(攻撃者視点で見ると最強)

攻撃者が典型的な payload を試しても…

javascript:alert(1)
<img src=x onerror=alert(1)>
<svg><script>alert(1)</script>

これらが innerHTML に到達した瞬間、ブラウザが:

「TrustedHTML じゃないので拒否します」

とブロックする。

DOM XSS の最大の弱点だった
“開発者のミス” を、Trusted Types がルール化して潰してくれる。


5. 実務で使えるサニタイズパターン

Trusted Types と組み合わせる最強の方法は:

DOMPurify + Trusted Types + CSP

const policy = trustedTypes.createPolicy("default", {
  createHTML(input) {
    return DOMPurify.sanitize(input, {RETURN_TRUSTED_TYPE: true});
  }
});

こうすれば:

  • DOMPurify が悪意 HTML を削除
  • Trusted Types が“危険 API の入口”を封鎖
  • CSP が JS 実行をさらに制限

三段構えで XSS を防げる。


6. Trusted Types の注意点(落とし穴)

落とし穴 説明
SPA フレームワークで影響出る可能性 React/Vue/Angular が内部で innerHTML を使っている場合あり
初期導入時エラーが大量発生する TT がブロックしている証拠だが、修正コストが発生
柔軟すぎる createPolicy 実装 ポリシーがザルだと意味がない

特に React の dangerouslySetInnerHTML は、
Trusted Types と併用する場合は専用設定が必要


まとめ — Trusted Types は DOM XSS の“最終兵器”

Trusted Types を導入すると:

  • innerHTML を直接使えなくなる

    → 開発者のミスで DOM XSS が発生しない

  • TrustedHTML だけ許可される

    → 悪意 HTML が通らない

  • CSP と組み合わせると「ほぼ完全防御」

    → XSS の攻撃面が激減

  • DOMPurify と併用すると実務最強構成

    → Web アプリ全体の堅牢性が大幅アップ

Trusted Types は「現代の Web が抱える DOM XSS 問題に対する決定的な解決策」。

Google、Gmail、YouTube、Twitter など大規模サービスで採用されている理由はそこにある。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?