概要
- setHTML() はHTML文字列を安全にDOMへ挿入するためのメソッド
- XSS対策 として、危険な要素や属性を自動で除去
- SanitizerやSanitizerConfig によるカスタマイズ可能
- Element.innerHTML や setHTMLUnsafe() より安全
- Trusted Types API による検証は行われない
setHTML() メソッドの概要
- setHTML(input, options) は、HTML文字列を安全にパースし、要素内に挿入するDOMメソッド
- input :サニタイズ対象となるHTML文字列
- options(省略可能) :サニタイズ方法を指定するオブジェクト
- sanitizer :Sanitizerインスタンス、SanitizerConfigオブジェクト、または"default"文字列を指定可能
- 戻り値 :なし(undefined)
- 例外 :TypeError
- 不正なSanitizerConfig (allowedとremoved両方指定など)、"default"以外の文字列、型不一致時に発生
setHTML() の動作詳細
- XSS対策 として、HTML文字列から危険な要素や属性を自動で削除
- 要素の文脈依存性 を考慮し、無効な要素(例:<col>が<table>外にある場合)も除去
- Sanitizer設定 で許可されていても、危険な要素・属性は必ず削除
- options.sanitizer 未指定時は デフォルトSanitizer が適用
- デフォルトは「安全」と判断された要素・属性のみ許可
- カスタムSanitizer/SanitizerConfig で許可・除去要素や属性、コメントなどを柔軟に指定可能
- Sanitizer.removeUnsafe() が暗黙的に呼ばれるため、常に安全性を確保
使用推奨シーン
- Element.innerHTML の代替として、信頼できないHTML文字列の挿入
- Element.setHTMLUnsafe() の代替(安全性を重視する場合)
- XSSリスク低減 を目的としたDOM操作
具体的な使い方
- デフォルトSanitizerの場合
- 例:
const unsanitizedString = "abc <script>alert(1)</script> def"; const target = document.getElementById("target"); target.setHTML(unsanitizedString); // <script>タグは除去される
- 例:
- カスタムSanitizerの利用
- 例:
const sanitizer1 = new Sanitizer({ elements: ["div", "p", "button", "script"] }); target.setHTML(unsanitizedString, { sanitizer: sanitizer1 }); // script要素も除去
- 例:
- SanitizerConfigを直接指定
- 例:
target.setHTML(unsanitizedString, { sanitizer: { removeElements: ["div", "p", "button", "script"] } });
- 例:
ライブデモの流れ
- HTML構成
- 複数のボタン(Default, allowScript, Reload)
- 挿入対象の<div>とログ表示用<pre>
- JavaScript処理
- sanitizer適用ボタン でsetHTMLを実行し、サニタイズ前後の内容をログに出力
- defaultSanitizer :危険な要素・属性はすべて除去
- allowScriptSanitizer :script要素を許可してもsetHTMLでは除去される
- Reloadボタン :ページリロードで初期化
- Sanitizer未対応ブラウザ :代替処理案内
結果・注意事項
- どのSanitizer設定でも<script>要素やonclick属性は除去
- setHTML()は常に安全性を最優先
- Trusted Types API による追加の検証は行われない点に留意
参考リンク
- HTML Sanitizer API仕様 :HTML Sanitizer API# dom-element-sethtml
- 関連API
- Element.setHTMLUnsafe()
- ShadowRoot.setHTML(), ShadowRoot.setHTMLUnsafe()
- Document.parseHTML(), Document.parseHTMLUnsafe()
- 公式ドキュメント参照推奨