HTML Sanitizer APIの初見レビュー
innerHTMLを使用してユーザー生成コンテンツをレンダリングしたことがある場合、何らかのレベルのXSSリスクを受け入れたことになります。通常の対処法は、DOMPurifyのようなライブラリを導入して、まず文字列をサニタイズすることです。これは機能しますが、追加のJavaScriptを配信し、ブラウザの進化するパーサー動作に対応し続けるためにサードパーティを信頼する必要があります。HTML Sanitizer APIは、この問題に対するブラウザの答えです。そして、まだすべての環境で本番利用できる状態ではないとしても、今理解しておく価値があります。
重要なポイント
innerHTMLは安全性チェックなしにマークアップを解析して挿入するため、ユーザー生成コンテンツを扱う際に持続的なXSS攻撃ベクトルとなります。- HTML Sanitizer APIは、
Element.setHTML()のような安全なメソッドを導入し、コンテンツをDOMに挿入する前にスクリプト、イベントハンドラ、危険なURLを自動的に除去します。 Sanitizerを許可リストまたは削除リストで構成することで、サニタイゼーション後にどの要素と属性を残すかを正確に制御できます。- 2026年初頭の時点でブラウザサポートはまだ限定的であるため、本番コードでは機能検出を使用し、DOMPurifyにフォールバックする必要があります。
なぜinnerHTMLは常にリスクだったのか
innerHTMLは要求されたことを正確に実行します。文字列を解析し、結果をDOMに挿入します。質問なしに。これは便利ですが、誰かがコメントやユーザー名として<img src=x onerror="stealCookies()">を渡すまでの話です。
DOMPurifyのようなライブラリは、文字列を自ら解析し、結果のDOMツリーをウォークし、危険なものをすべて除去してから返すことで、この問題に対処します。これは効果的ですが脆弱です。ブラウザのパーサー動作は時間とともに変化し、ユーザースペースに存在するライブラリはこれらの変化を常に追いかけなければなりません。一方、ブラウザ自体は、特定のマークアップをどのように解析して実行するかを常に正確に把握しています。
HTML Sanitizer APIが提供するもの
ネイティブHTML Sanitizer APIは、サニタイゼーションをブラウザに移行します。innerHTMLを直接設定する代わりに、解析、サニタイズ、挿入を一度に行う新しいメソッドを使用します。
安全なメソッドは、最も頻繁に使用するものです:
Element.setHTML()ShadowRoot.setHTML()Document.parseHTML()
これらは、渡された構成に関係なく、常にXSS非安全コンテンツ—<script>タグ、onclickのようなイベントハンドラ属性、ナビゲーション属性内のjavascript: URL—を除去します。構成なしでは、setHTML()は基本的に自動XSS保護を備えたinnerHTMLのドロップイン置き換えです:
const userContent = `<p>Hello!</p><script>alert('xss')<\/script>`;
document.getElementById("output").setHTML(userContent);
// レンダリング結果: <p>Hello!</p>
// <script>は静かに削除されます
非安全なメソッド—setHTMLUnsafe()、ShadowRoot.setHTMLUnsafe()、Document.parseHTMLUnsafe()—は、より多くの制御を提供します。これらは、XSS安全ベースラインを強制せずに、提供したサニタイザー構成のみを適用します。これらは、安全なメソッドがブロックする要素や属性を許可する特定の理由がある場合にのみ、慎重に構築された構成とともに使用してください。
Discover how at OpenReplay.com.
Sanitizerの構成
両方のメソッドファミリーは、オプションのSanitizerインスタンスまたは構成ディクショナリを受け入れます。許可構成(許可されるものを正確に指定し、それ以外をすべて削除)または削除構成(除去するものを指定し、それ以外をすべて許可)を構築できます。
許可構成は一般的により安全な選択です:
const sanitizer = new Sanitizer({
elements: ["p", "b", "em", "a"],
attributes: ["href"]
});
document.getElementById("comments").setHTML(untrustedInput, { sanitizer });
Sanitizerクラスは、内部的に一貫性を保ちながらプログラム的に構成を変更するためのallowElement()やremoveElement()のようなメソッドも公開しています。
ブラウザサポートとその対処法
正直な状況は次のとおりです: 2026年初頭の時点で、HTML Sanitizer APIはブラウザへの搭載が始まったばかりです。Firefox 148がサポートを追加し、Chrome 146がそれに続きましたが、広範なクロスブラウザ対応はまだ追いついていません。これはまだBaseline Webプラットフォームの一部ではないため、今日すべてのユーザーで利用可能であることに依存することはできません。現在のサポート状況はCan I Useで確認できます。
本番コードでは、機能検出を使用し、DOMPurifyにフォールバックしてください:
if (typeof Element.prototype.setHTML === "function") {
element.setHTML(untrustedHTML);
} else {
element.innerHTML = DOMPurify.sanitize(untrustedHTML);
}
結論
HTML Sanitizer APIは、ブラウザ標準が行うべきことを正確に表しています: 危険で広く誤って扱われているパターンを取り上げ、安全な道を簡単な道にすることです。setHTML()対innerHTMLはまだ本当の議論ではありません—ブラウザサポートがその決定をあなたのために行います。しかし、今APIを理解することは、サポートが広がるにつれて採用する準備ができることを意味し、ブラウザネイティブHTMLサニタイゼーションが実際に何を行うように設計されているかについて、より明確な見通しを持つことができます。
よくある質問
確実にはできません。2026年初頭の時点で、FirefoxとChromeがサポートを提供していますが、このAPIはまだ限定的な利用可能機能であり、Baseline Webプラットフォームの一部ではありません。本番アプリケーションでは、機能検出を使用してElement.prototype.setHTMLを確認し、APIが利用できない場合はDOMPurifyのようなライブラリにフォールバックしてください。これにより、サポートされている場所ではネイティブサニタイゼーションを利用しながら、他のすべての場所で安全性を維持できます。
setHTMLは常にベースラインのXSS安全ポリシーを強制します。構成に関係なく、スクリプトタグ、イベントハンドラ属性、危険なURLを除去します。setHTMLUnsafeは、その安全ネットなしに、提供したサニタイザー構成のみを適用します。setHTMLUnsafeは、安全なメソッドがブロックする要素や属性を明示的に許可する必要がある場合にのみ使用してください。
まだです。DOMPurifyは、Sanitizer APIサポートを欠くブラウザのフォールバックとして必要です。ブラウザカバレッジが普遍的になったとしても、DOMPurifyは一部のプロジェクトが必要とするより細かい構成オプションを提供します。しかし、時間が経つにつれて、ネイティブAPIはサードパーティの依存関係を必要とせずに、大部分のサニタイゼーションユースケースを処理するはずです。
許可構成は、許可される要素と属性を正確に指定し、それ以外をすべて削除します。削除構成は、除去するものを指定し、明示的にリストされていないすべてを許可します。許可構成は、未知の要素や新しい要素を誤って許可するのではなく、デフォルトでブロックするため、一般的により安全です。
Complete picture for complete understanding
Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.
Check our GitHub repo and join the thousands of developers in our community.