2月25日、Mozillaが「Goodbye innerHTML, Hello setHTML: Stronger XSS Protection in Firefox 148 – Mozilla Hacks」と題した記事を公開した。この記事では、Firefox 148で導入された標準化済みのSanitizer APIと、それを用いたXSS対策の強化、およびブラウザ間の実装状況について詳しく紹介されている。
以下に、その内容を紹介する。
XSS対策の新機軸:Sanitizer API
ウェブ開発において、信頼できないHTMLを安全にDOMに挿入することは長年の課題であった。従来の innerHTML は、挿入時にスクリプトを自動実行してしまうリスクを孕んでいる。これに対し、Firefox 148で導入された Sanitizer API の setHTML() メソッドは、挿入プロセス自体にサニタイズ(無害化)を組み込んでいる。これにより、悪意のあるスクリプトやイベントハンドラが自動的に除去される「セーフ・バイ・デフォルト」な環境が提供される。
setHTML() の基本とカスタマイズ
setHTML() は第2引数にオプションを渡すことで、特定の要素や属性のみを許可する高度な制御が可能だ。
実装例:許可リストの指定
const sanitizerOptions = {
elements: ['b', 'i', 'em', 'strong'],
attributes: ['class', 'id']
};
const rawHTML = `<b class="important" onclick="alert(1)">Hello</b> <u>World</u>`;
document.getElementById('output').setHTML(rawHTML, sanitizerOptions);
このコードでは、<b> は維持されるが、許可されていない <u> 要素はタグのみが削除され、危険な onclick 属性も排除される。
Trusted Typesとの連携
さらに強固なセキュリティを求める場合、Sanitizer APIを Trusted Types と組み合わせる手法が有効である。Trusted Typesは、ブラウザ側で「生の文字列」をDOM挿入関数に渡すことを禁止し、検証済みのオブジェクトのみを許可する仕組みである。
setHTML() を採用したサイトでは、Trusted Typesのポリシーを適用することで、将来的なデグレード(不適切な innerHTML の使用など)を未然に防ぐことができる。
標準化と実装の現状
現在、これらのセキュリティAPIはW3C/WICGにおいて標準化が進められており、各ブラウザでの実装も進展している。
| 機能 | 標準化の状態 | 主要ブラウザの実装状況 |
|---|---|---|
Sanitizer API (setHTML) |
WICG草案 | Firefox 148で標準仕様として初搭載。Chrome/Edgeも順次対応予定。 |
| Trusted Types API | W3C勧告候補 | Chrome, Edge, Firefoxでサポート済み。 |
Firefox 148がSanitizer APIを正式にサポートしたことで、主要ブラウザ間での足並みが揃いつつある。これにより、開発者はサードパーティ製ライブラリ(DOMPurifyなど)に依存せず、ブラウザ標準の機能だけでセキュアなアプリケーションを構築できる道が開かれた。
導入によるメリット
- 容易な移行:
innerHTMLをsetHTML()に置換するだけで、セキュリティレベルが向上する。 - パフォーマンス: ブラウザネイティブの実装であるため、JavaScriptベースのライブラリよりも高速かつ効率的な処理が期待できる。
- 将来の安全性: Trusted Typesと併用することで、プロジェクト全体でのHTML挿入ルールを強制し、人為的なミスによる脆弱性の混入を防げる。
結論
Sanitizer APIは、ウェブプラットフォームにおけるセキュリティを「後付けの対策」から「ブラウザ標準の仕様」へと変える重要なステップである。setHTML() と Trusted Types を組み合わせることで、開発者は複雑な実装変更を伴わずに、XSSの脅威からユーザーを保護することが可能となる。
詳細はGoodbye innerHTML, Hello setHTML: Stronger XSS Protection in Firefox 148 – Mozilla Hacksを参照していただきたい。