Edition for Web Developers — Last Updated 11 August 2026
マークアップを文書に動的に挿入するためのAPIはパーサーと相互作用するため、その動作は、HTML文書(およびHTMLパーサー)かXML文書(およびXMLパーサー)かのどちらで使用されるかによって異なる。
document = document.open()前のオブジェクトを再利用する場合を除き、あたかもそれが新しいDocumentオブジェクトであるかのように、Documentに正しい場所で置換され、その後返される。
結果として得られるDocumentはHTMLパーサーが関連付けられており、 document.write()を使用して解析するデータを与えることができる。
Documentがまだ解析されている場合、メソッドは効果がない。
DocumentがXML文書である場合、"InvalidStateError" DOMExceptionを投げる。
パーサーがカスタム要素コンストラクターを現在実行している場合、"InvalidStateError" DOMExceptionを投げる。
window = document.open(url, name, features)window.open()メソッドのように動作する。
document.close()document.open()メソッドによって開かれた入力ストリームを閉じる。
DocumentがXML文書である場合、"InvalidStateError" DOMExceptionを投げる。
パーサーがカスタム要素コンストラクターを現在実行している場合、"InvalidStateError" DOMExceptionを投げる。
document.write()document.write(...text)一般に、与えられた文字列をDocumentの入力ストリームに加える。
このメソッドは非常に特異な振る舞いを持つ。一部の場合において、このメソッドは、パーサーが実行されている間、HTMLパーサーの状態に影響を与えることができる。その結果、文書のソースに対応しないDOMをもたらす(たとえば、記述された文字列が、文字列"<plaintext>"または"<!--"である場合)。他の例では、あたかもdocument.open()が呼び出されていたかのように、呼び出しが最初に現在のページをクリアできる。さらに多くの例では、メソッドは単に無視されるか、または例外を投げる。User agents are explicitly allowed to avoid executing script elements inserted via this method. さらに悪いことに、このメソッドの正確な動作は、場合によってはネットワーク遅延に依存する可能性があり、これはデバッグが非常に困難な障害につながる可能性がある。これらすべての理由から、このメソッドの使用は強く勧めない。
XML文書で呼び出されるとき、"InvalidStateError" DOMExceptionを投げる。
パーサーがカスタム要素コンストラクターを現在実行している場合、"InvalidStateError" DOMExceptionを投げる。
このメソッドは、scriptまたはイベントハンドラーコンテンツ属性のような潜在的に危険な要素および属性を削除するためのサニタイズを実行しない。
document.writeln()document.writeln(...text)改行文字の後に、与えられた文字列をDocumentの入力ストリームに加える。必要ならば、open()メソッドを暗黙のうちに最初に呼び出す。
このメソッドは非常に特異な振る舞いを持つ。Use of this method is strongly discouraged, for the same reasons as document.write().
XML文書で呼び出されるとき、"InvalidStateError" DOMExceptionを投げる。
パーサーがカスタム要素コンストラクターを現在実行している場合、"InvalidStateError" DOMExceptionを投げる。
このメソッドは、scriptまたはイベントハンドラーコンテンツ属性のような潜在的に危険な要素および属性を削除するためのサニタイズを実行しない。
Support in all current engines.
DOMParserインターフェイスDOMParser インターフェイスは、HTMLまたはXMLのいずれかとして、文字列を解析することで新しいDocumentオブジェクトを作成することを可能にする。
parser = new DOMParser()新しいDOMParserオブジェクトを構築する。
document = parser.parseFromString(string, type)typeに応じて、HTMLまたはXMLパーサーのいずれかを使用して文字列を解析し、結果のDocumentを返す。typeは、"text/html"(HTMLパーサーを呼び出す)、または"text/xml"、"application/xml"、"application/xhtml+xml"、もしくは"image/svg+xml"(XMLパーサーを呼び出す)。
XMLパーサーの場合、文字列を解析できない場合、返されるDocumentは、結果のエラーを説明する要素が含まれる。
script 要素は解析中に評価されず、結果の文書のエンコーディングは常にUTF-8となることに注意する。文書のURLは、parserの関連するグローバルオブジェクトから継承される。
typeに上記以外の値を指定すると、TypeError例外が投げられる。
構築してからparseFromString()メソッドを呼び出す必要があるクラスとしてのDOMParserの設計は、不幸な歴史的成果物である。もし今日にこの機能を設計していたとしたら、それはスタンドアロン機能になっただろう。HTMLを解析する場合、現在の代替手段はDocument.parseHTMLUnsafe()である。
このメソッドは、scriptまたはイベントハンドラーコンテンツ属性のような潜在的に危険な要素および属性を削除するためのサニタイズを実行しない。
element.setHTML(html, options)Parses html using the HTML parser with options options, and replaces the children of element with the result. element provides context for the HTML parser. The parsed fragment is sanitized based on the options's "sanitizer" member, and unsafe content is removed.
shadowRoot.setHTML(html, options)Parses html using the HTML parser with options options, and replaces the children of shadowRoot with the result. shadowRoot's host provides context for the HTML parser. The parsed fragment is sanitized based on the options's "sanitizer" member, and unsafe content is removed.
element.setHTMLUnsafe(html, options)Parses html using the HTML parser with options options, and replaces the children of element with the result. element provides context for the HTML parser. If the options dictionary contains a "sanitizer" member, it is used to sanitize the parsed fragment before it is inserted into element. If the options dictionary's "runScripts" member is true, scripts contained in html will be executed immediately after the node tree is updated.
shadowRoot.setHTMLUnsafe(html, options)Parses html using the HTML parser with options options, and replaces the children of shadowRoot with the result. shadowRoot's host provides context for the HTML parser. If the options dictionary contains a "sanitizer" member, it is used to sanitize the parsed fragment before it is inserted into shadowRoot. If the options dictionary's "runScripts" member is true, scripts contained in html will be executed immediately after the node tree is updated.
doc = Document.parseHTML(html, options)Parses html using the HTML parser with options options, and returns a new Document containing the result. The resulting document is sanitized based on the options's "sanitizer" member, and unsafe content is removed.
doc = Document.parseHTMLUnsafe(html, options)オプションoptionsをもつHTMLパーサーを使用してhtmlを解析し、結果Documentを返す。
script 要素は解析中に評価されず、結果の文書のエンコーディングは常にUTF-8となることに注意する。文書のURLは、about:blankになる。options辞書に"sanitizer"メンバーが含まれている場合、結果のDOMをサニタイズするために使用される。
The methods with an Unsafe suffix perform no sanitization to remove potentially-dangerous elements and attributes like script or event handler content attributes.
html = element.getHTML({ serializableShadowRoots, shadowRoots })elementをHTMLにシリアル化した結果を返す。element内のシャドウルートは、指定されたオプションに従ってシリアル化される。
serializableShadowRootsがtrueの場合、シリアル化可能とマークされたすべてのシャドウルートがシリアル化される。
shadowRoots配列が指定されている場合、シリアル化可能としてマークされているかどうかに関係なく、配列で指定されたすべてのシャドウルートがシリアル化される。
どちらのオプションも指定しない場合、シャドウルートはシリアル化されない。
html = shadowRoot.getHTML({ serializableShadowRoots, shadowRoots })コンテキスト要素としてシャドウホストを使用して、shadowRootをHTMLにシリアル化した結果を返す。shadowRoot内のシャドウルートは、上記のように、指定されたオプションに従ってシリアル化される。
innerHTMLプロパティinnerHTMLプロパティには、DOM Parsing and Serialization issue trackerに未解決の問題が多数あり、その仕様に関するさまざまな問題が文書化されている。
element.innerHTML要素の内容を表すHTMLまたはXMLのフラグメントを返す。
XML文書の場合、要素をXMLにシリアル化できない場合、"InvalidStateError" DOMExceptionを投げる。
element.innerHTML = value要素の内容を、指定された文字列から解析されたノードに置き換える。
XML文書の場合、指定した文字列が整形式でない場合、"SyntaxError" DOMExceptionを投げる。
shadowRoot.innerHTMLシャドウルートの内容を表すHTMLのフラグメントを返す。
shadowRoot.innerHTML = valueシャドウルートの内容を、指定した文字列から解析されたノードに置き換える。
これらのプロパティのセッターは、scriptまたはイベントハンドラーコンテンツ属性などの潜在的に危険な要素および属性を削除するためのサニタイズを実行しない。
outerHTMLプロパティouterHTMLプロパティには、DOM Parsing and Serialization issue trackerに未解決の問題が多数あり、その仕様に関するさまざまな問題が文書化されている。
element.outerHTML要素とその内容を表すHTMLまたはXMLのフラグメントを返す。
XML文書の場合、要素をXMLにシリアル化できない場合、"InvalidStateError" DOMExceptionを投げる。
element.outerHTML = value要素を、指定された文字列から解析されたノードに置き換える。
XML文書の場合、指定した文字列が整形式でない場合、"SyntaxError" DOMExceptionを投げる。
要素の親がDocumentである場合、"NoModificationAllowedError" DOMExceptionを返す。
このプロパティのセッターは、scriptまたはイベントハンドラーコンテンツ属性などの潜在的に危険な要素および属性を削除するためのサニタイズを実行しない。
insertAdjacentHTML()メソッドinsertAdjacentHTML()メソッドには、DOM Parsing and Serialization issue trackerに未解決の問題が多数あり、その仕様に関するさまざまな問題が文書化されている。
element.insertAdjacentHTML(position, string)stringをHTMLまたはXMLとして解析し、結果のノードを次のようにposition引数で指定された位置にツリーに挿入する:
beforebegin"afterbegin"beforeend"afterend"引数に無効な値が含まれている場合に"SyntaxError" DOMExceptionを投げる(たとえば、XML文書の場合、指定された文字列が整形式でない場合)。
指定した位置が使用できない場合に"NoModificationAllowedError" DOMExceptionを投げる(たとえば、Documentのルート要素の後に要素を挿入する場合など)。
このメソッドは、scriptまたはイベントハンドラーコンテンツ属性のような潜在的に危険な要素および属性を削除するためのサニタイズを実行しない。
createContextualFragment()メソッドcreateContextualFragment()メソッドには、DOM Parsing and Serialization issue trackerに未解決の問題が多数あり、その仕様に関するさまざまな問題が文書化されている。
docFragment = range.createContextualFragment(string)fragmentが解析されるコンテキストとしてrangeの開始ノードを使用して、マークアップ文字列stringから作成された DocumentFragmentを返す。
このメソッドは、scriptまたはイベントハンドラーコンテンツ属性のような潜在的に危険な要素および属性を削除するためのサニタイズを実行しない。
XMLSerializerインターフェイス>XMLSerializeインターフェイスには、DOM Parsing and Serialization issue trackerに未解決の問題が多数あり、その仕様に関するさまざまな問題が文書化されている。DOM Parsing and Serializationの残りの部分は、この仕様に徐々にアップストリームされまる。
xmlSerializer = new XMLSerializer()新しいXMLSerializerオブジェクトを構築する。
string = xmlSerializer.serializeToString(root)rootをXMLにシリアル化した結果を返す。
rootをXMLにシリアル化できない場合、"InvalidStateError" DOMExceptionを投げる。
構築してからserializeToString()メソッドを呼び出す必要があるクラスとしてのXMLSerializerの設計は、不幸な歴史的成果物である。もし今日にこの機能を設計していたとしたら、それはスタンドアロン機能になっただろう。
ウェブアプリケーションでは、ユーザー生成コンテンツのレンダリングまたはクライアントサイドテンプレートの使用時など、信頼できないHTML文字列を処理する必要があることがよくある。これらの文字列をDOMに安全に挿入するには、DOMベースのクロスサイトスクリプティング(XSS)攻撃を防ぐために、慎重なサニタイゼーションが必要である。
HTMLサニタイゼーションは、HTML文字列を安全に解析し、サニタイズするためのネイティブなメカニズムを提供する。ユーザーエージェント独自のHTMLパーサーを使用することで、サニタイズされた出力が、ブラウザーがコンテンツをレンダリングする方法を正確に反映することを保証し、スクリプトの実行を防ぎ、スクリプトガジェットなどの高度な攻撃を軽減する。
これらのAPIは、HTMLを含む文字列を解析してDOMツリーを作成し、ユーザーが指定した設定に従って結果のツリーをフィルタリングする機能を提供する。この方法には、"安全"と"安全でない"という2つの主要なフレーバーがある。
"安全な"メソッドは、スクリプトを実行するマークアップを生成しない。つまり、これらはXSSから安全であることを目的としている。"安全でない"メソッドは、提供された構成に基づいて解析とフィルタリングを行うが、デフォルトでは同じ安全性を保証しない。
Sanitizerインターフェイスconfig = sanitizer.get()サニタイザーのconfigurationを返す。
sanitizer.allowElement(element)サニタイザーの設定で、指定された要素が許可されるようにする。
sanitizer.removeElement(element)サニタイザーの設定が指定された要素をブロックするようにする。
sanitizer.replaceElementWithChildren(element)指定された要素を削除するが、その子ノードを保持するようにサニタイザーを設定する。
sanitizer.allowAttribute(attribute)指定された属性をグローバルに許可するようにサニタイザーを設定する。
sanitizer.removeAttribute(attribute)指定された属性をグローバルにブロックするようにサニタイザーを設定する。
sanitizer.allowProcessingInstruction(pi)指定された処理命令を許可するようにサニタイザーを設定する。
sanitizer.removeProcessingInstruction(pi)指定された処理命令をブロックするようにサニタイザーを設定する。
sanitizer.setComments(allow)コメントを保持するかどうかを設定する。
sanitizer.setDataAttributes(allow)サニタイザーがカスタムデータ属性(たとえばdata-*)を保持するかどうかを設定する。
sanitizer.removeUnsafe()安全でないと見なされる要素および属性を自動的に削除するように設定を変更する。
A Sanitizer object has an associated configuration, which is a SanitizerConfig.
The new Sanitizer(configuration) constructor steps are:
To configure a Sanitizer sanitizer, given a dictionary configuration and a boolean allowCommentsPIsAndDataAttributes:
Canonicalize the configuration configuration with allowCommentsPIsAndDataAttributes.
If configuration is not valid, then throw a TypeError.
Set sanitizer's configuration to configuration.
To canonicalize the configuration SanitizerConfig configuration with a boolean allowCommentsPIsAndDataAttributes:
If neither configuration["elements"] nor configuration["removeElements"] exists, then set configuration["removeElements"] to an empty list.
If neither configuration["attributes"] nor configuration["removeAttributes"] exists, then set configuration["removeAttributes"] to an empty list.
If neither configuration["processingInstructions"] nor configuration["removeProcessingInstructions"] exists:
If allowCommentsPIsAndDataAttributes is true, then set configuration["removeProcessingInstructions"] to an empty list.
Otherwise, set configuration["processingInstructions"] to an empty list.
If configuration["elements"] exists:
If configuration["removeElements"] exists, then set configuration["removeElements"] to the result of canonicalizing configuration["removeElements"].
If configuration["attributes"] exists, then set configuration["attributes"] to the result of canonicalizing configuration["attributes"].
If configuration["removeAttributes"] exists, then set configuration["removeAttributes"] to the result of canonicalizing configuration["removeAttributes"].
If configuration["replaceWithChildrenElements"] exists, then set configuration["replaceWithChildrenElements"] to the result of canonicalizing configuration["replaceWithChildrenElements"].
If configuration["processingInstructions"] exists, then set configuration["processingInstructions"] to the result of canonicalizing configuration["processingInstructions"].
If configuration["removeProcessingInstructions"] exists, then set configuration["removeProcessingInstructions"] to the result of canonicalizing configuration["removeProcessingInstructions"].
If configuration["comments"] does not exist, then set it to allowCommentsPIsAndDataAttributes.
If configuration["attributes"] exists and configuration["dataAttributes"] does not exist, then set it to allowCommentsPIsAndDataAttributes.
To canonicalize a sanitizer list list:
Let newList be « ».
For each item in list, append the result of canonicalizing item to newList.
Return newList.
To canonicalize a processing instruction list list:
Let newList be « ».
For each item in list, append the result of canonicalizing item to newList.
Return newList.
To canonicalize a processing instruction given a SanitizerPI pi:
To canonicalize a sanitizer name given a DOMString or dictionary name, and a default namespace defaultNamespace (default null):
To canonicalize a sanitizer element given a SanitizerElement element:
Return the result of canonicalizing element with the HTML namespace as the default namespace.
To canonicalize a sanitizer element list list:
Let newList be « ».
For each item in list, append the result of canonicalizing item to newList.
Return newList.
To find the canonicalized intersection of lists A and B:
Let setA be « ».
Let setB be « ».
For each entry of A, append the result of canonicalizing entry to setA.
For each entry of B, append the result of canonicalizing entry to setB.
Return the intersection of setA and setB.
The get() method steps are:
Outside of the get() method, the order of the Sanitizer's elements and attributes is unobservable. By explicitly sorting the result of this method, we give implementations the opportunity to optimize by, for example, using unordered sets internally.
Let config be this's configuration.
Assert: config is valid.
If config["elements"] exists:
For each element of config["elements"]:
If element["attributes"] exists, then set element["attributes"] to the result of sorting element["attributes"], with compare sanitizer items.
If element["removeAttributes"] exists, then set element["removeAttributes"] to the result of sorting element["removeAttributes"], with compare sanitizer items.
Set config["elements"] to the result of sorting config["elements"], with compare sanitizer items.
Otherwise:
Set config["removeElements"] to the result of sorting config["removeElements"], with compare sanitizer items.
If config["replaceWithChildrenElements"] exists, then set config["replaceWithChildrenElements"] to the result of sorting config["replaceWithChildrenElements"], with compare sanitizer items.
If config["processingInstructions"] exists, then set config["processingInstructions"] to the result of sorting config["processingInstructions"], with piA["target"] being code unit less than piB["target"].
Otherwise:
Set config["removeProcessingInstructions"] to the result of sorting config["removeProcessingInstructions"], with piA["target"] being code unit less than piB["target"].
If config["attributes"] exists, then set config["attributes"] to the result of sorting config["attributes"] given compare sanitizer items.
Otherwise:
Set config["removeAttributes"] to the result of sorting config["removeAttributes"] given compare sanitizer items.
Return config.
The allowElement(element) method steps are:
Let configuration be this's configuration.
Assert: configuration is valid.
Set element to the result of canonicalizing element.
If configuration["elements"] exists:
Let modified be the result of removing element from configuration["replaceWithChildrenElements"].
If configuration["attributes"] exists:
If element["attributes"] exists:
Set element["attributes"] to the result of creating a set from element["attributes"].
Set element["attributes"] to the difference of element["attributes"] and configuration["attributes"].
If configuration["dataAttributes"] is true, then remove all items item from element["attributes"] where item is a custom data attribute.
If element["removeAttributes"] exists:
Set element["removeAttributes"] to the result of creating a set from element["removeAttributes"].
Set element["removeAttributes"] to the intersection of element["removeAttributes"] and configuration["attributes"].
Otherwise:
If element["attributes"] exists:
Set element["attributes"] to the result of creating a set from element["attributes"].
Set element["attributes"] to the difference of element["attributes"] and element["removeAttributes"] with default « ».
Remove element["removeAttributes"].
Set element["attributes"] to the difference of element["attributes"] and configuration["removeAttributes"].
If element["removeAttributes"] exists:
Set element["removeAttributes"] to the result of creating a set from element["removeAttributes"].
Set element["removeAttributes"] to the difference of element["removeAttributes"] and configuration["removeAttributes"].
If configuration["elements"] does not contain element:
Append element to configuration["elements"].
Return true.
Let currentElement be the item in configuration["elements"] whose name member is element's name member and whose namespace member is element's namespace member.
If element is equal to currentElement, then return modified.
Remove element from configuration["elements"].
Append element to configuration["elements"].
Return true.
Otherwise:
If element["attributes"] exists or element["removeAttributes"] with default « » is not empty, then return false.
Let modified be the result of removing element from configuration["replaceWithChildrenElements"].
If configuration["removeElements"] does not contain element, then return modified.
Remove element from configuration["removeElements"].
Return true.
The removeElement(element) method steps are to return the result of removing element from this's configuration.
The replaceElementWithChildren(element) method steps are:
Let configuration be this's configuration.
Assert: configuration is valid.
Set element to the result of canonicalizing element.
If the built-in non-replaceable elements list contains element, then return false.
Let modified be the result of removing element from configuration["elements"].
If removing element from configuration["removeElements"] is true, then set modified to true.
If configuration["replaceWithChildrenElements"] does not contain element:
Append element to configuration["replaceWithChildrenElements"].
Return true.
Return modified.
The allowAttribute(attribute) method steps are:
Let configuration be this's configuration.
Assert: configuration is valid.
Set attribute to the result of canonicalizing attribute.
If configuration["attributes"] exists:
If configuration["dataAttributes"] is true and attribute is a custom data attribute, then return false.
If configuration["attributes"] contains attribute, then return false.
If configuration["elements"] exists:
For each element in configuration["elements"]:
If element["attributes"] with default « » contains attribute, then remove attribute from element["attributes"].
Append attribute to configuration["attributes"].
Return true.
Otherwise:
The removeAttribute(attribute) method steps are to return the result of removing attribute from this's configuration.
The setComments(allow) method steps are:
Let configuration be this's configuration.
Assert: configuration is valid.
If configuration["comments"] exists and is equal to allow, then return false.
Set configuration["comments"] to allow.
Return true.
The setDataAttributes(allow) method steps are:
Let configuration be this's configuration.
Assert: configuration is valid.
If configuration["attributes"] does not exist, then return false.
If configuration["dataAttributes"] exists and is equal to allow, then return false.
If allow is true:
If configuration["elements"] exists:
For each element of configuration["elements"]:
If element["attributes"] exists, then remove all items item from element["attributes"] where item is a custom data attribute.
Remove all items item from configuration["attributes"] where item is a custom data attribute.
Set configuration["dataAttributes"] to allow.
Return true.
The allowProcessingInstruction(pi) method steps are:
Let configuration be this's configuration.
Assert: configuration is valid.
Set pi to the result of canonicalizing pi.
If configuration["processingInstructions"] exists:
Otherwise:
The removeProcessingInstruction(pi) method steps are:
Let configuration be this's configuration.
Assert: configuration is valid.
Set pi to the result of canonicalizing pi.
If configuration["processingInstructions"] exists:
Otherwise:
The removeUnsafe() method steps are to return the result of removing unsafe from this's configuration.
SanitizerElementNamespace、SanitizerAttributeNamespace、SanitizerElementNamespaceWithAttributes、およびSanitizerProcessingInstructionディクショナリーは、それらのすべてのメンバーが等しい場合に等しいと見なされる。
同等性は、代わりにinfra仕様で定義すべきである。See issue #664.
設定は、開発者が目的に合わせて変更することができ、また変更すべきである。オプションは、新しいSanitizerConfigディクショナリーを最初から作成するか、修飾子メソッドを使用して既存のSanitizerの設定を変更するか、既存のSanitizerの設定をディクショナリーとしてget()し、ディクショナリーを変更してから、それを使用して新しいSanitizerを作成することである。
空の設定はすべてを許可する(setHTMLUnsafe()のような"安全でない"メソッドで呼び出された場合)。設定"デフォルト"には、組み込みの安全なデフォルト設定が含まれる。"安全な"および"安全でない"サニタイザー方法は、異なるデフォルトを持つことに注意する。
Not all configuration dictionaries are valid. A valid configuration avoids redundancy (like specifying the same element to be allowed twice) and contradictions (like specifying an element to be both removed and allowed.)
Several conditions need to hold for a configuration to be valid:
Mixing global allow- and remove-lists:
elements or removeElements can exist, but not both. If both are missing, this is equivalent to removeElements being an empty list.
attributes or removeAttributes can exist, but not both. If both are missing, this is equivalent to removeAttributes being an empty list.
dataAttributes is conceptually an extension of the attributes allow-list. The dataAttributes member is only allowed when an attributes list is used.
Duplicate entries between different global lists:
There are no duplicate entries (i.e., no same elements) between elements, removeElements, or replaceWithChildrenElements.
There are no duplicate entries (i.e., no same attributes) between attributes or removeAttributes.
Mixing local allow- and remove-lists on the same element:
When an attributes list exists, both, either or none of the attributes and removeAttributes lists are allowed on the same element.
When a removeAttributes list exists, either or none of the attributes and removeAttributes lists are allowed on the same element, but not both.
Duplicate entries on the same element:
There are no duplicate entries between attributes and removeAttributes on the same element.
No element from the built-in non-replaceable elements list appears in replaceWithChildrenElements, since replacing these elements with their children could lead to re-parsing issues or invalid node trees.
The elements element allow-list can also specify allowing or removing attributes for a given element. This is meant to mirror this standard's structure, which knows both global attributes as well as local attributes that apply to a specific element. Global and local attributes can be mixed, but note that ambiguous configurations where a particular attribute would be allowed by one list and forbidden by another, are generally invalid.
global attributes | global removeAttributes | |
|---|---|---|
local attributes | An attribute is allowed if it matches either list. No duplicates are allowed. | An attribute is only allowed if it's in the local allow list. No duplicate entries between global remove and local allow lists are allowed. Note that the global remove list has no function for this particular element, but can apply to other elements that do not have a local allow list. |
local removeAttributes | An attribute is allowed if it's in the global allow-list, but not in the local remove-list. Local remove has to be a subset of the global allow lists. | An attribute is allowed if it is in neither list. No duplicate entries between global remove and local remove lists are allowed. |
Please note the asymmetry where mostly no duplicates between global and per-element lists are permitted, but in the case of a global allow-list and a per-element remove-list the latter has to be a subset of the former. An excerpt of the table above, only focusing on duplicates, is as follows:
global attributes | global removeAttributes | |
|---|---|---|
local attributes | No duplicates are allowed. | No duplicates are allowed. |
local removeAttributes | Local remove has to be a subset of the global allow lists. | No duplicates are allowed. |
The dataAttributes setting allows custom data attributes. The rules above easily extends to custom data attributes if one considers dataAttributes to be an allow-list:
global attributes and dataAttributes set | |
|---|---|
local attributes | All custom data attributes are allowed. No custom data attributes can be listed in any allow-list, as that would mean a duplicate entry. |
local removeAttributes | A custom data attribute is allowed, unless it's listed in the local remove-list. No custom data attribute can be listed in the global allow-list, as that would mean a duplicate entry. |
Putting these rules in words:
Duplicates and interactions between global and local lists:
If a global attributes allow list exists, then all element's local lists:
If a local attributes allow list exists, there can be no duplicate entries between these lists.
If a local removeAttributes remove list exists, then all its entries also need to be listed in the global attributes allow list.
If dataAttributes is true, then no custom data attributes can be listed in any of the allow-lists.
If a global removeAttributes remove list exists:
If a local attributes allow list exists, there can be no duplicate entries between these lists.
If a local removeAttributes remove list exists, there can be no duplicate entries between these lists.
Not both a local attributes allow list and local removeAttributes remove list exists.
dataAttributes has to be false.
サニタイザーAPIは、提供されたHTMLコンテンツをトラバースし、構成に応じて要素および属性を削除することで、DOMベースのクロスサイトスクリプティングを防止することを目的としている。設計上、setHTML()およびparseHTML()メソッドは、提供された構成に関係なく、スクリプト対応のマークアップを削除する。これらのメソッドを使用してそのようなマークアップを保持できる構成がある場合、それはバグになる。
しかし、サニタイザーAPIでは防ぐことができないセキュリティ上の問題がある。次のセクションでは、それらについて説明する。
サニタイザーAPIはDOM内でのみ動作し、既存のDocumentFragmentをトラバースしてフィルタリングする機能を追加する。サニタイザーAPIは、サーバー側で反映または保存されたXSSには対応していない。
DOMクローバリングとは、悪意のあるHTMLがidまたはname属性を使用してアプリケーションを混乱させ、HTML要素のchildrenプロパティなどのDOMプロパティを悪意のあるコンテンツによってシャドウイング(上書き)してしまう攻撃のことである。
サニタイザーAPIは、デフォルトではDOMクローバリング攻撃から保護しないが、idおよびname属性を削除するように設定できる。
スクリプトガジェットは、攻撃者が広く使われているJavaScriptライブラリーの既存のアプリケーションコードを使用して、独自のコードを実行させる手法である。これは多くの場合、無害に見えるコード、またはフレームワークによって解析および解釈されるだけの外見上は不活性なDOMノードを注入し、その入力に基づいてJavaScriptを実行することによって行われる。
サニタイザーAPIは、これらの攻撃を防ぐことができない。その代わりに、著者が一般的に未知の要素を明示的に許可することに加えて、data-*およびslot属性ならびにslotおよびtemplateのような要素など、テンプレートおよびフレームワーク固有のコードに一般に使用される属性、要素、およびマークアップを明示的に許可することに依存している。これらの制限はすべてを網羅しているわけではなく、著者はこの動作についてサードパーティのライブラリを調査することを推奨する。
ミューテーションXSSまたはmXSSは、解析されたDOM構造がシリアル化と再解析の後に同じでない場合につけこんで、シリアル化前に発生するサニタイゼーションをバイパスする攻撃を説明する。そのような攻撃を実行するための例は、外来コンテンツまたは誤ってネストされたタグの解析動作の変更に依存することである。
サニタイザーAPIは、文字列をノードツリーに変換する関数のみを提供する。コンテキストは、すべてのサニタイザー関数によって暗黙的に提供される。setHTML()は現在の要素を使用し、Document.parseHTML()は新しい文書を作成する。したがって、サニタイザーAPIはミューテーションXSSの影響を直接受けない。
もし開発者がサニタイズされたノードツリーをinnerHTMLなどを介して文字列として取得し、再度解析するならば、ミューテーションXSSが発生する可能性がある。この行為は、強く推奨しない。結局のところ、HTMLを文字列として処理または渡す必要がある場合、文字列は信頼できないと見なされ、DOMに挿入されるときに再サニタイズされる。言い換えれば、サニタイズされてからシリアル化されたHTMLツリーは、もはやサニタイズされたとは見なされない。mXSSのより完全な処置については、[MXSS]を参照。