Living Standard — Last Updated 12 June 2026
マークアップを文書に動的に挿入するためのAPIはパーサーと相互作用するため、その動作は、HTML文書(およびHTMLパーサー)かXML文書(およびXMLパーサー)かのどちらで使用されるかによって異なる。
Document objects have a throw-on-dynamic-markup-insertion counter, which is used in conjunction with the create an element for the token algorithm to prevent custom element constructors from being able to use document.open(), document.close(), and document.write() when they are invoked by the parser. Initially, the counter must be set to zero.
document = document.open()Support in all current engines.
前のオブジェクトを再利用する場合を除き、あたかもそれが新しいDocumentオブジェクトであるかのように、Documentに正しい場所で置換され、その後返される。
結果として得られるDocumentはHTMLパーサーが関連付けられており、 document.write()を使用して解析するデータを与えることができる。
Documentがまだ解析されている場合、メソッドは効果がない。
DocumentがXML文書である場合、"InvalidStateError" DOMExceptionを投げる。
パーサーがカスタム要素コンストラクターを現在実行している場合、"InvalidStateError" DOMExceptionを投げる。
window = document.open(url, name, features)window.open()メソッドのように動作する。
Document objects have an active parser was aborted boolean, which is used to prevent scripts from invoking the document.open() and document.write() methods (directly or indirectly) after the document's active parser has been aborted. 最初はfalseである。
The document open steps, given a document, are as follows:
If document is an XML document, then throw an "InvalidStateError" DOMException.
If document's throw-on-dynamic-markup-insertion counter is greater than 0, then throw an "InvalidStateError" DOMException.
Let entryDocument be the entry global object's associated Document.
If document's origin is not same origin to entryDocument's origin, then throw a "SecurityError" DOMException.
If document has an active parser whose script nesting level is greater than 0, then return document.
This basically causes document.open() to be ignored when it's called in an inline script found during parsing, while still letting it have an effect when called from a non-parser task such as a timer callback or event handler.
Similarly, if document's unload counter is greater than 0, then return document.
This basically causes document.open() to be ignored when it's called from a beforeunload, pagehide, or unload event handler while the Document is being unloaded.
If document's active parser was aborted is true, then return document.
This notably causes document.open() to be ignored if it is called after a navigation has started, but only during the initial parse. See issue #4723 for more background.
If document's node navigable is non-null and document's node navigable's ongoing navigation is a navigation ID, then stop loading document's node navigable.
For each shadow-including inclusive descendant node of document, erase all event listeners and handlers given node.
If document is the associated Document of document's relevant global object, then erase all event listeners and handlers given document's relevant global object.
Replace all with null within document.
If document is fully active:
Let newURL be a copy of entryDocument's URL.
If entryDocument is not document, then set newURL's fragment to null.
Run the URL and history update steps with document and newURL.
Set document's is initial about:blank to false.
If document's iframe load in progress flag is set, then set document's mute iframe load flag.
Set document to no-quirks mode.
Create a new HTML parser and associate it with document. This is a script-created parser (meaning that it can be closed by the document.open() and document.close() methods, and that the tokenizer will wait for an explicit call to document.close() before emitting an end-of-file token). The encoding confidence is irrelevant.
Set the insertion point to point at just before the end of the input stream (which at this point will be empty).
Update the current document readiness of document to "loading".
This causes a readystatechange event to fire, but the event is actually unobservable to author code, because of the previous step which erased all event listeners and handlers that could observe it.
documentを返す。
The document open steps do not affect whether a Document is ready for post-load tasks or completely loaded.
The open(unused1, unused2) method must return the result of running the document open steps with this.
The unused1 and unused2 arguments are ignored, but kept in the IDL to allow code that calls the function with one or two arguments to continue working. They are necessary due to Web IDL overload resolution algorithm rules, which would throw a TypeError exception for such calls had the arguments not been there. whatwg/webidl issue #581 investigates changing the algorithm to allow for their removal. [WEBIDL]
The open(url, name, features) method must run these steps:
If this is not fully active, then throw an "InvalidAccessError" DOMException.
Return the result of running the window open steps with url, name, and features.
document.close()Support in all current engines.
document.open()メソッドによって開かれた入力ストリームを閉じる。
DocumentがXML文書である場合、"InvalidStateError" DOMExceptionを投げる。
パーサーがカスタム要素コンストラクターを現在実行している場合、"InvalidStateError" DOMExceptionを投げる。
The close() method must run the following steps:
If this is an XML document, then throw an "InvalidStateError" DOMException.
If this's throw-on-dynamic-markup-insertion counter is greater than zero, then throw an "InvalidStateError" DOMException.
If there is no script-created parser associated with this, then return.
Insert an explicit "EOF" character at the end of the parser's input stream.
If this's pending parsing-blocking script is not null, then return.
Run the tokenizer, processing resulting tokens as they are emitted, and stopping when the tokenizer reaches the explicit "EOF" character or spins the event loop.
document.write()document.write(...text)Support in all current engines.
一般に、与えられた文字列を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 objects have an ignore-destructive-writes counter, which is used in conjunction with the processing of script elements to prevent external scripts from being able to use document.write() to blow away the document by implicitly calling document.open(). Initially, the counter must be set to zero.
The document write steps, given a Document object document, a list text, a boolean lineFeed, and a string sink, are as follows:
Let string be the empty string.
Let isTrusted be false if text contains a string; otherwise true.
For each value of text:
If value is a TrustedHTML object, then append value's associated data to string.
Otherwise, append value to string.
If isTrusted is false, set string to the result of invoking the get trusted type compliant string algorithm with TrustedHTML, this's relevant global object, string, sink, and "script".
If lineFeed is true, append U+000A LINE FEED to string.
If document is an XML document, then throw an "InvalidStateError" DOMException.
If document's throw-on-dynamic-markup-insertion counter is greater than 0, then throw an "InvalidStateError" DOMException.
If document's active parser was aborted is true, then return.
If the insertion point is undefined:
If document's unload counter is greater than 0 or document's ignore-destructive-writes counter is greater than 0, then return.
Run the document open steps with document.
Insert string into the input stream just before the insertion point.
If document's pending parsing-blocking script is null, then have the HTML parser process string, one code point at a time, processing resulting tokens as they are emitted, and stopping when the tokenizer reaches the insertion point or when the processing of the tokenizer is aborted by the tree construction stage (this can happen if a script end tag token is emitted by the tokenizer).
If the document.write() method was called from script executing inline (i.e. executing because the parser parsed a set of script tags), then this is a reentrant invocation of the parser. If the parser pause flag is set, the tokenizer will abort immediately and no HTML will be parsed, per the tokenizer's parser pause flag check.
The document.write(...text) method steps are to run the document write steps with this, text, false, and "Document write".
document.writeln()document.writeln(...text)Support in all current engines.
改行文字の後に、与えられた文字列をDocumentの入力ストリームに加える。必要ならば、open()メソッドを暗黙のうちに最初に呼び出す。
このメソッドは非常に特異な振る舞いを持つ。Use of this method is strongly discouraged, for the same reasons as document.write().
XML文書で呼び出されるとき、"InvalidStateError" DOMExceptionを投げる。
パーサーがカスタム要素コンストラクターを現在実行している場合、"InvalidStateError" DOMExceptionを投げる。
このメソッドは、scriptまたはイベントハンドラーコンテンツ属性のような潜在的に危険な要素および属性を削除するためのサニタイズを実行しない。
The document.writeln(...text) method steps are to run the document write steps with this, text, true, and "Document writeln".
Support in all current engines.
partial interface Element {
[CEReactions ] undefined setHTML (DOMString html , optional SetHTMLOptions options = {});
[CEReactions ] undefined setHTMLUnsafe ((TrustedHTML or DOMString ) html , optional SetHTMLUnsafeOptions options = {});
DOMString getHTML (optional GetHTMLOptions options = {});
[CEReactions ] attribute (TrustedHTML or [LegacyNullToEmptyString ] DOMString ) innerHTML ;
[CEReactions ] attribute (TrustedHTML or [LegacyNullToEmptyString ] DOMString ) outerHTML ;
[CEReactions ] undefined insertAdjacentHTML (DOMString position , (TrustedHTML or DOMString ) string );
};
partial interface ShadowRoot {
[CEReactions ] undefined setHTML (DOMString html , optional SetHTMLOptions options = {});
[CEReactions ] undefined setHTMLUnsafe ((TrustedHTML or DOMString ) html , optional SetHTMLUnsafeOptions options = {});
DOMString getHTML (optional GetHTMLOptions options = {});
[CEReactions ] attribute (TrustedHTML or [LegacyNullToEmptyString ] DOMString ) innerHTML ;
};
enum SanitizerPresets { " default " };
dictionary SetHTMLOptions {
(Sanitizer or SanitizerConfig or SanitizerPresets ) sanitizer = "default";
};
dictionary SetHTMLUnsafeOptions {
(Sanitizer or SanitizerConfig or SanitizerPresets ) sanitizer = {};
boolean runScripts = false ;
};
dictionary ParseHTMLUnsafeOptions {
(Sanitizer or SanitizerConfig or SanitizerPresets ) sanitizer = {};
};
dictionary GetHTMLOptions {
boolean serializableShadowRoots = false ;
sequence <ShadowRoot > shadowRoots = [];
};
DOMParserインターフェイスDOMParser インターフェイスは、HTMLまたはXMLのいずれかとして、文字列を解析することで新しいDocumentオブジェクトを作成することを可能にする。
parser = new DOMParser()Support in all current engines.
新しいDOMParserオブジェクトを構築する。
document = parser.parseFromString(string, type)Support in all current engines.
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またはイベントハンドラーコンテンツ属性のような潜在的に危険な要素および属性を削除するためのサニタイズを実行しない。
[Exposed =Window ]
interface DOMParser {
constructor ();
[NewObject ] Document parseFromString ((TrustedHTML or DOMString ) string , DOMParserSupportedType type );
};
enum DOMParserSupportedType {
" text/html " ,
" text/xml " ,
" application/xml " ,
" application/xhtml+xml " ,
" image/svg+xml "
};
The new DOMParser() constructor steps are to do nothing.
The parseFromString(string, type) method steps are:
Let compliantString be the result of invoking the get trusted type compliant string algorithm with TrustedHTML, this's relevant global object, string, "DOMParser parseFromString", and "script".
Let document be a new Document, whose content type is type and URL is this's relevant global object's associated Document's URL.
The document's encoding will be left as its default, of UTF-8. In particular, any XML declarations or meta elements found while parsing compliantString will have no effect.
Switch on type:
text/html"Parse HTML from a string given document and compliantString.
Since document does not have a browsing context, scripting is disabled.
Create an XML parser parser, associated with document, and with XML scripting support disabled.
Parse compliantString using parser.
If the previous step resulted in an XML well-formedness or XML namespace well-formedness error:
Assert: document has no child nodes.
Let root be the result of creating an element given document, "parsererror", and "http://www.mozilla.org/newlayout/xml/parsererror.xml".
Optionally, add attributes or children to root to describe the nature of the parsing error.
Append root to document.
documentを返す。
To parse HTML from a string, given a Document document and a string html:
Set document's type to "html".
Create an HTML parser parser, associated with document.
Place html into the input stream for parser. The encoding confidence is irrelevant.
Start parser and let it run until it has consumed all the characters just inserted into the input stream.
This might mutate the document's mode.
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)Parses html using the HTML parser with options options, and returns the resulting Document.
script 要素は解析中に評価されず、結果の文書のエンコーディングは常にUTF-8となることに注意する。文書のURLは、about:blankになる。If the options dictionary contains a "sanitizer" member, it is used to sanitize the resulting DOM.
The methods with an Unsafe suffix perform no sanitization to remove potentially-dangerous elements and attributes like script or event handler content attributes.
Element's setHTML(html, options) method steps are:
Let target be this's template contents if this is a template element; otherwise this.
Set and filter HTML given target, this, html, options, and true.
ShadowRoot's setHTML(html, options) method steps are:
Set and filter HTML given this, this's shadow host, html, options, and true.
Element's setHTMLUnsafe(html, options) method steps are:
Let compliantHTML be the result of invoking the get trusted type compliant string algorithm with TrustedHTML, this's relevant global object, html, "Element setHTMLUnsafe", and "script".
Let target be this's template contents if this is a template element; otherwise this.
Set and filter HTML given target, this, compliantHTML, options, and false.
ShadowRoot's setHTMLUnsafe(html, options) method steps are:
Let compliantHTML be the result of invoking the get trusted type compliant string algorithm with TrustedHTML, this's relevant global object, html, "ShadowRoot setHTMLUnsafe", and "script".
Set and filter HTML given this, this's shadow host, compliantHTML, options, and false.
The static parseHTML(html, options) method steps are:
Let document be a new Document, whose content type is "text/html".
Since document does not have a browsing context, scripting is disabled.
Set document's allow declarative shadow roots to true.
Parse HTML from a string given document and html.
Let sanitizer be the result of calling get a sanitizer instance from options with options and true.
Call sanitize on document with sanitizer and true.
documentを返す。
The static parseHTMLUnsafe(html, options) method steps are:
Let compliantHTML be the result of invoking the get trusted type compliant string algorithm with TrustedHTML, this's relevant global object, html, "Document parseHTMLUnsafe", and "script".
Let document be a new Document, whose content type is "text/html".
Since document does not have a browsing context, scripting is disabled.
Set document's allow declarative shadow roots to true.
Parse HTML from a string given document and compliantHTML.
Let sanitizer be the result of calling get a sanitizer instance from options with options and false.
Call sanitize on document with sanitizer and false.
documentを返す。
html = element.getHTML({ serializableShadowRoots, shadowRoots })elementをHTMLにシリアル化した結果を返す。element内のシャドウルートは、指定されたオプションに従ってシリアル化される。
serializableShadowRootsがtrueの場合、シリアル化可能とマークされたすべてのシャドウルートがシリアル化される。
shadowRoots配列が指定されている場合、シリアル化可能としてマークされているかどうかに関係なく、配列で指定されたすべてのシャドウルートがシリアル化される。
どちらのオプションも指定しない場合、シャドウルートはシリアル化されない。
html = shadowRoot.getHTML({ serializableShadowRoots, shadowRoots })コンテキスト要素としてシャドウホストを使用して、shadowRootをHTMLにシリアル化した結果を返す。shadowRoot内のシャドウルートは、上記のように、指定されたオプションに従ってシリアル化される。
Element's getHTML(options) method steps are to return the result of HTML fragment serialization algorithm with this, options["serializableShadowRoots"], and options["shadowRoots"].
ShadowRoot's getHTML(options) method steps are to return the result of HTML fragment serialization algorithm with this, options["serializableShadowRoots"], and options["shadowRoots"].
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またはイベントハンドラーコンテンツ属性などの潜在的に危険な要素および属性を削除するためのサニタイズを実行しない。
The fragment serializing algorithm steps, given an Element, Document, or DocumentFragment node and a boolean require well-formed, are:
Let context document be node's node document.
If context document is an HTML document, return the result of HTML fragment serialization algorithm with node, false, and « ».
Return the XML serialization of node given require well-formed.
The fragment parsing algorithm steps, given an Element context, a string markup, and an optional parser scripting mode scriptingMode (default Inert), are:
Let newChildren be null.
If context's node document is an XML document, then set newChildren to the result of invoking the XML fragment parsing algorithm given context and markup.
Otherwise, set newChildren to the result of invoking the HTML fragment parsing algorithm given context, markup, false, and scriptingMode.
Let fragment be a new DocumentFragment whose node document is context's node document.
For each node of newChildren, in tree order: append node to fragment.
This ensures the node document for the new nodes is correct.
Return fragment.
Element's innerHTML getter steps are to return the result of running fragment serializing algorithm steps with this and true.
ShadowRoot's innerHTML getter steps are to return the result of running fragment serializing algorithm steps with this and true.
Element's innerHTML setter steps are:
Let compliantString be the result of invoking the get trusted type compliant string algorithm with TrustedHTML, this's relevant global object, the given value, "Element innerHTML", and "script".
Let context be this.
Let fragment be the result of invoking the fragment parsing algorithm steps with context and compliantString.
If context is a template element, then set context to the template element's template contents (a DocumentFragment).
Setting innerHTML on a template element will replace all the nodes in its template contents rather than its children.
Replace all with fragment within context.
ShadowRoot's innerHTML setter steps are:
Let compliantString be the result of invoking the get trusted type compliant string algorithm with TrustedHTML, this's relevant global object, the given value, "ShadowRoot innerHTML", and "script".
Let fragment be the result of invoking the fragment parsing algorithm steps with context and compliantString.
Replace all with fragment within this.
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またはイベントハンドラーコンテンツ属性などの潜在的に危険な要素および属性を削除するためのサニタイズを実行しない。
Element's outerHTML getter steps are:
Let element be a fictional node whose only child is this.
Return the result of running fragment serializing algorithm steps with element and true.
Element's outerHTML setter steps are:
Let compliantString be the result of invoking the get trusted type compliant string algorithm with TrustedHTML, this's relevant global object, the given value, "Element outerHTML", and "script".
If parent is null, return. There would be no way to obtain a reference to the nodes created even if the remaining steps were run.
If parent is a Document, throw a "NoModificationAllowedError" DOMException.
If parent is a DocumentFragment, set parent to the result of creating an element given this's node document, "body", and the HTML namespace.
Let fragment be the result of invoking the fragment parsing algorithm steps given parent and compliantString.
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またはイベントハンドラーコンテンツ属性のような潜在的に危険な要素および属性を削除するためのサニタイズを実行しない。
Element's insertAdjacentHTML(position, string) method steps are:
Let compliantString be the result of invoking the get trusted type compliant string algorithm with TrustedHTML, this's relevant global object, string, "Element insertAdjacentHTML", and "script".
Let context be null.
Use the first matching item from this list:
beforebegin"afterend"If context is null or a Document, throw a "NoModificationAllowedError" DOMException.
afterbegin"beforeend"Throw a "SyntaxError" DOMException.
If context is not an Element or all of the following are true:
context's node document is an HTML document;
context's local name is "html"; and
context's namespace is the HTML namespace,
then set context to the result of creating an element given this's node document, "body", and the HTML namespace.
Let fragment be the result of invoking the fragment parsing algorithm steps with context and compliantString.
beforebegin"afterbegin"Insert fragment into this before its first child.
beforeend"afterend"Insert fragment into this's parent before this's next sibling.
As with other direct Node-manipulation APIs (and unlike innerHTML), insertAdjacentHTML() does not include any special handling for template elements. In most cases you will want to use templateEl.content.insertAdjacentHTML() instead of directly manipulating the child nodes of a template element.
createContextualFragment()メソッドcreateContextualFragment()メソッドには、DOM Parsing and Serialization issue trackerに未解決の問題が多数あり、その仕様に関するさまざまな問題が文書化されている。
docFragment = range.createContextualFragment(string)fragmentが解析されるコンテキストとしてrangeの開始ノードを使用して、マークアップ文字列stringから作成された DocumentFragmentを返す。
このメソッドは、scriptまたはイベントハンドラーコンテンツ属性のような潜在的に危険な要素および属性を削除するためのサニタイズを実行しない。
partial interface Range {
[CEReactions , NewObject ] DocumentFragment createContextualFragment ((TrustedHTML or DOMString ) string );
};
Range's createContextualFragment(string) method steps are:
Let compliantString be the result of invoking the get trusted type compliant string algorithm with TrustedHTML, this's relevant global object, string, "Range createContextualFragment", and "script".
Let node be this's start node.
Let element be null.
If node implements Element, set element to node.
Otherwise, if node implements Text or Comment, set element to node's parent element.
If element is null or all of the following are true:
element's node document is an HTML document;
element's local name is "html"; and
element's namespace is the HTML namespace,
then set element to the result of creating an element given this's node document, "body", and the HTML namespace.
Return the result of invoking the fragment parsing algorithm steps with element, compliantString, and Fragment.
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の設計は、不幸な歴史的成果物である。もし今日にこの機能を設計していたとしたら、それはスタンドアロン機能になっただろう。
[Exposed =Window ]
interface XMLSerializer {
constructor ();
DOMString serializeToString (Node root );
};
The new XMLSerializer() constructor steps are to do nothing.
The serializeToString(root) method steps are:
Return the XML serialization of root given false.
この節は非規範的である。
Web applications often need to process untrusted HTML strings, such as when rendering user-generated content or using client-side templates. Safely inserting these strings into the DOM requires careful sanitization to prevent DOM-based cross-site scripting (XSS) attacks.
HTML sanitization provides a native mechanism for safely parsing and sanitizing HTML strings. By using the user agent's own HTML parser, they ensure the sanitized output accurately reflects how the browser will render the content, preventing script execution and mitigating advanced attacks such as script gadgets.
These APIs offer functionality to parse a string containing HTML into a DOM tree, and to filter the resulting tree according to a user-supplied configuration. The methods come in two main flavors: "safe" and "unsafe".
The "safe" methods will not generate any markup that executes script. That is, they are intended to be safe from XSS. The "unsafe" methods will parse and filter based on the provided configuration, but do not have the same safety guarantees by default.
Sanitizer interface[Exposed =Window ]
interface Sanitizer {
constructor (optional (SanitizerConfig or SanitizerPresets ) configuration = "default");
// Query configuration:
SanitizerConfig get ();
// Modify a Sanitizer's lists and fields:
boolean allowElement (SanitizerElementWithAttributes element );
boolean removeElement (SanitizerElement element );
boolean replaceElementWithChildren (SanitizerElement element );
boolean allowProcessingInstruction (SanitizerPI pi );
boolean removeProcessingInstruction (SanitizerPI pi );
boolean allowAttribute (SanitizerAttribute attribute );
boolean removeAttribute (SanitizerAttribute attribute );
boolean setComments (boolean allow );
boolean setDataAttributes (boolean allow );
// Remove markup that executes script.
boolean removeUnsafe ();
};
config = sanitizer.get()Returns a copy of the sanitizer's configuration.
sanitizer.allowElement(element)Ensures that the sanitizer configuration allows the specified element.
sanitizer.removeElement(element)Ensures that the sanitizer configuration blocks the specified element.
sanitizer.replaceElementWithChildren(element)Configures the sanitizer to remove the specified element but keep its child nodes.
sanitizer.allowAttribute(attribute)Configures the sanitizer to allow the specified attribute globally.
sanitizer.removeAttribute(attribute)Configures the sanitizer to block the specified attribute globally.
sanitizer.allowProcessingInstruction(pi)Configures the sanitizer to allow the specified processing instruction.
sanitizer.removeProcessingInstruction(pi)Configures the sanitizer to block the specified processing instruction.
sanitizer.setComments(allow)Sets whether the sanitizer preserves comments.
sanitizer.setDataAttributes(allow)Sets whether the sanitizer preserves custom data attributes (e.g., data-*).
sanitizer.removeUnsafe()Modifies the configuration to automatically remove elements and attributes that are considered unsafe.
A Sanitizer object has an associated configuration, which is a SanitizerConfig.
The new Sanitizer(configuration) constructor steps are:
If configuration is a SanitizerPresets string:
Set configuration to the built-in safe default configuration.
To configure a Sanitizer sanitizer, given a dictionary configuration and a boolean allowCommentsPIsAndDataAttributes:
Canonicalize the configuration configuration with allowCommentsPIsAndDataAttributes.
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:
Let newElements be « ».
For each element of configuration["elements"], append the result of canonicalizing element to newElements.
Set configuration["elements"] to newElements.
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.
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.
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"].
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.
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.
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.
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:
If configuration["removeAttributes"] does not contain attribute, then return false.
Remove attribute from configuration["removeAttributes"].
Return true.
The removeAttribute(attribute) method steps are to return the result of removing attribute from this's configuration.
The setComments(allow) method steps are:
The setDataAttributes(allow) method steps are:
Let configuration be this's configuration.
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.
Set pi to the result of canonicalizing pi.
If configuration["processingInstructions"] exists:
If configuration["processingInstructions"] contains pi, then return false.
Append pi to configuration["processingInstructions"].
Return true.
Otherwise:
If configuration["removeProcessingInstructions"] contains pi:
Remove pi from configuration["removeProcessingInstructions"].
Return true.
falseを返す。
The removeProcessingInstruction(pi) method steps are:
Let configuration be this's configuration.
Set pi to the result of canonicalizing pi.
If configuration["processingInstructions"] exists:
If configuration["processingInstructions"] contains pi:
Remove pi from configuration["processingInstructions"].
Return true.
falseを返す。
Otherwise:
If configuration["removeProcessingInstructions"] contains pi, then return false.
Append pi to configuration["removeProcessingInstructions"].
Return true.
The removeUnsafe() method steps are to return the result of removing unsafe from this's configuration.
dictionary SanitizerElementNamespace {
required DOMString name ;
DOMString ? _namespace = "http://www.w3.org/1999/xhtml";
};
// Used by "elements"
dictionary SanitizerElementNamespaceWithAttributes : SanitizerElementNamespace {
sequence <SanitizerAttribute > attributes ;
sequence <SanitizerAttribute > removeAttributes ;
};
dictionary SanitizerAttributeNamespace {
required DOMString name ;
DOMString ? _namespace = null ;
};
dictionary SanitizerProcessingInstruction {
required DOMString target ;
};
typedef (DOMString or SanitizerElementNamespace ) SanitizerElement ;
typedef (DOMString or SanitizerElementNamespaceWithAttributes ) SanitizerElementWithAttributes ;
typedef (DOMString or SanitizerProcessingInstruction ) SanitizerPI ;
typedef (DOMString or SanitizerAttributeNamespace ) SanitizerAttribute ;
dictionary SanitizerConfig {
sequence <SanitizerElementWithAttributes > elements ;
sequence <SanitizerElement > removeElements ;
sequence <SanitizerElement > replaceWithChildrenElements ;
sequence <SanitizerPI > processingInstructions ;
sequence <SanitizerPI > removeProcessingInstructions ;
sequence <SanitizerAttribute > attributes ;
sequence <SanitizerAttribute > removeAttributes ;
boolean comments ;
boolean dataAttributes ;
};
SanitizerElementNamespace, SanitizerAttributeNamespace, SanitizerElementNamespaceWithAttributes, and SanitizerProcessingInstruction dictionaries are considered equal when all of their members are equal.
Equality should be defined in the infra spec instead. See issue #664.
この節は非規範的である。
Configurations can and ought to be modified by developers to suit their purposes. Options are to write a new SanitizerConfig dictionary from scratch, to modify an existing Sanitizer's configuration by using the modifier methods, or to get() an existing Sanitizer's configuration as a dictionary and modify the dictionary and then create a new Sanitizer with it.
An empty configuration allows everything (when called with the "unsafe" methods like setHTMLUnsafe()). A configuration "default" contains a built-in safe default configuration. Note that "safe" and "unsafe" sanitizer methods have different defaults.
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.
To set and filter HTML, given an Element or DocumentFragment target, an Element contextElement, a string html, a dictionary options, and a boolean safe:
If all of the following are true:
safe;
contextElement's local name is "script"; and
contextElement's namespace is the HTML namespace or the SVG namespace,
then return.
Let sanitizer be the result of calling getting a sanitizer from options given safe.
Let scriptingMode be Inert.
If options["runScripts"] is true:
Let newChildren be the result of parsing a fragment given contextElement, html, true, and scriptingMode.
Scripts in newChildren will only execute once inserted into target.
Let fragment be a new DocumentFragment whose node document is contextElement's node document.
Sanitize fragment given sanitizer and safe.
Replace all with fragment within target.
To get a sanitizer instance from options from a dictionary options with a boolean safe:
Let sanitizerSpec be "default".
If options["sanitizer"] exists, then set sanitizerSpec to options["sanitizer"].
Assert: sanitizerSpec is either a Sanitizer instance, a SanitizerPresets member, or a SanitizerConfig dictionary.
If sanitizerSpec is a string:
Set sanitizerSpec to the built-in safe default configuration.
If sanitizerSpec is a dictionary:
Return sanitizerSpec.
To sanitize a Node node with a Sanitizer sanitizer and a boolean safe:
Let configuration be sanitizer's configuration.
If safe is true, then remove unsafe from configuration.
Run the inner sanitize steps given node, configuration, and safe.
To perform the inner sanitize steps given a Node node, a SanitizerConfig configuration, and a boolean handleJavascriptNavigationUrls:
For each child of node's children:
Assert: child is a Text, Comment, Element, ProcessingInstruction, or DocumentType node.
If child is a DocumentType or Text node, then continue.
If child is a Comment node:
If child is a ProcessingInstruction node:
Let piTarget be child's target.
If configuration["processingInstructions"] exists:
If configuration["processingInstructions"] does not contain piTarget, then remove child.
Otherwise:
If configuration["removeProcessingInstructions"] contains piTarget, then remove child.
Otherwise:
Let elementName be a SanitizerElementNamespace with child's local name and namespace.
If configuration["replaceWithChildrenElements"] exists and configuration["replaceWithChildrenElements"] contains elementName:
Run the inner sanitize steps given child, configuration, and handleJavascriptNavigationUrls.
Let fragment be a new DocumentFragment whose node document is node's node document.
For each innerChild of child's children, append innerChild to fragment.
Replace child with fragment within node. Assert that this did not throw.
Otherwise:
If configuration["removeElements"] contains elementName, then remove child and continue.
If elementName["name"] is "template" and elementName["namespace"] is the HTML namespace, then run the inner sanitize steps given child's template contents, configuration, and handleJavascriptNavigationUrls.
If child is a shadow host, then run the inner sanitize steps given child's shadow root, configuration, and handleJavascriptNavigationUrls.
Let elementWithLocalAttributes be «[ ]».
If configuration["elements"] exists and configuration["elements"] contains elementName, then set elementWithLocalAttributes to configuration["elements"][elementName].
For each attribute in child's attribute list:
Let attrName be a SanitizerAttributeNamespace with attribute's local name and namespace.
If elementWithLocalAttributes["removeAttributes"] exists and elementWithLocalAttributes["removeAttributes"] contains attrName, then remove attribute.
Otherwise, if configuration["attributes"] exists:
If configuration["attributes"] does not contain attrName and elementWithLocalAttributes["attributes"] with default « » does not contain attrName, and if "data-" is not a code unit prefix of attribute's local name or attribute's namespace is not null or configuration["dataAttributes"] is not true, then remove attribute.
Otherwise:
If elementWithLocalAttributes["attributes"] exists and elementWithLocalAttributes["attributes"] does not contain attrName, then remove attribute.
Otherwise, if configuration["removeAttributes"] contains attrName, then remove attribute.
If handleJavascriptNavigationUrls is true:
If the pair (elementName, attrName) matches an entry in the built-in navigating URL attributes list, and if attribute contains a javascript: URL, then remove attribute.
If child's namespace is the MathML Namespace, attribute's local name is "href", attribute's namespace is null or the XLink namespace, and attribute contains a javascript: URL, then remove attribute.
If the built-in animating URL attributes list contains the pair (elementName, attrName), and attribute's value is "href" or "xlink:href", then remove attribute.
Run the inner sanitize steps given child, configuration, and handleJavascriptNavigationUrls.
To determine whether an attribute attribute contains a javascript: URL:
Let url be the result of running the basic URL parser on attribute's value.
If url is failure, then return false.
Return true if url's scheme is "javascript", and false otherwise.
To remove an element element from a SanitizerConfig configuration:
Set element to the result of canonicalizing element.
Let modified be the result of removing element from configuration["replaceWithChildrenElements"].
Otherwise:
If configuration["removeElements"] contains element, then return modified.
Append element to configuration["removeElements"].
Return true.
To remove an attribute attribute from a SanitizerConfig configuration:
Set attribute to the result of canonicalizing attribute.
If configuration["attributes"] exists:
Let modified be the result of removing attribute from configuration["attributes"].
If configuration["elements"] exists:
For each element of configuration["elements"]:
If element["attributes"] with default « » contains attribute:
Set modified to true.
Remove attribute from element["attributes"].
If element["removeAttributes"] with default « » contains attribute:
Assert: modified is true.
Remove attribute from element["removeAttributes"].
Return modified.
Otherwise:
If configuration["removeAttributes"] 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"].
If element["removeAttributes"] with default « » contains attribute, then remove attribute from element["removeAttributes"].
Append attribute to configuration["removeAttributes"].
Return true.
To remove unsafe from a SanitizerConfig configuration:
Let result be false.
For each element in built-in safe baseline configuration["removeElements"]:
If removing element from configuration is true, then set result to true.
For each attribute in built-in safe baseline configuration["removeAttributes"]:
If removing attribute from configuration is true, then set result to true.
For each attribute that is an event handler content attribute:
If removing attribute from configuration is true, then set result to true.
Return result.
To compare sanitizer items itemA and itemB:
Let namespaceA be itemA["namespace"].
Let namespaceB be itemB["namespace"].
If namespaceA is null:
If namespaceB is not null, then return true.
Otherwise:
If namespaceB is null, then return false.
If namespaceA is code unit less than namespaceB, then return true.
If namespaceA is not namespaceB, then return false.
If itemA["name"] is code unit less than itemB["name"], then return true.
falseを返す。
To canonicalize a SanitizerElementWithAttributes element:
Let result be the result of canonicalizing element.
If element is a dictionary:
If element["attributes"] exists, then set result["attributes"] to the result of canonicalizing element["attributes"].
If element["removeAttributes"] exists, then set result["removeAttributes"] to the result of canonicalizing element["removeAttributes"].
If neither result["attributes"] nor result["removeAttributes"] exists, then set result["removeAttributes"] to an empty list.
Return result.
To determine whether a canonical SanitizerConfig config is valid:
It's expected that the configuration being passed in has previously been run through the canonicalize the configuration steps. We will simply assert conditions that that algorithm is guaranteed to hold.
Assert: config["elements"] exists or config["removeElements"] exists.
If config["elements"] exists and config["removeElements"] exists, then return false.
Assert: Either config["processingInstructions"] exists or config["removeProcessingInstructions"] exists.
If config["processingInstructions"] exists and config["removeProcessingInstructions"] exists, then return false.
Assert: Either config["attributes"] exists or config["removeAttributes"] exists.
If config["attributes"] exists and config["removeAttributes"] exists, then return false.
Assert: All SanitizerElementNamespaceWithAttributes, SanitizerElementNamespace, SanitizerProcessingInstruction, and SanitizerAttributeNamespace items in config are canonical, meaning they have been run through canonicalizing, as appropriate.
If config["elements"] has duplicates, then return false.
Otherwise:
If config["removeElements"] has duplicates, then return false.
If config["replaceWithChildrenElements"] exists and has duplicates, then return false.
If config["processingInstructions"] exists:
If config["processingInstructions"] has duplicates, then return false.
Otherwise:
If config["removeProcessingInstructions"] has duplicates, then return false.
If config["attributes"] exists:
If config["attributes"] has duplicates, then return false.
Otherwise:
If config["removeAttributes"] has duplicates, then return false.
If config["replaceWithChildrenElements"] exists:
For each element of config["replaceWithChildrenElements"]:
If the built-in non-replaceable elements list contains element, then return false.
If the intersection of config["elements"] and config["replaceWithChildrenElements"] is not empty, then return false.
Otherwise:
If the intersection of config["removeElements"] and config["replaceWithChildrenElements"] is not empty, then return false.
If config["attributes"] exists:
Assert: config["dataAttributes"] exists.
For each element of config["elements"]:
If element["attributes"] exists and element["attributes"] has duplicates, then return false.
If element["removeAttributes"] exists and element["removeAttributes"] has duplicates, then return false.
If the intersection of config["attributes"] and element["attributes"] with default « » is not empty, then return false.
If element["removeAttributes"] with default « » is not a subset of config["attributes"], then return false.
If config["dataAttributes"] is true and element["attributes"] contains a custom data attribute, then return false.
If config["dataAttributes"] is true and config["attributes"] contains a custom data attribute, then return false.
Otherwise:
For each element of config["elements"]:
If element["attributes"] exists and element["removeAttributes"] exists, then return false.
If element["attributes"] exists and element["attributes"] has duplicates, then return false.
If element["removeAttributes"] exists and element["removeAttributes"] has duplicates, then return false.
If the intersection of config["removeAttributes"] and element["attributes"] with default « » is not empty, then return false.
If the intersection of config["removeAttributes"] and element["removeAttributes"] with default « » is not empty, then return false.
If config["dataAttributes"] exists, then return false.
Return true.
An element's sanitization category can be one of the following:
SanitizerConfig.setHTMLUnsafe() or parseHTMLUnsafe(), and removed by setHTML(), parseHTML(), and removeUnsafe().)SanitizerConfig.The built-in safe baseline configuration is a SanitizerConfig. Its removeElements list consists of all HTML elements normatively marked as Unsafe within their individual definitions, along with the obsolete frame element, and the SVG script and SVG use elements, and its removeAttributes list is empty.
Event handler content attributes are automatically removed by the remove unsafe algorithm during safe sanitization, so the effective baseline behaves as if they were included in the removeAttributes list.
The built-in safe default configuration is a SanitizerConfig whose members are initialized as follows:
processingInstructionsattributesdirlangtitlealignment-baselinebaseline-shiftclip-pathclip-rulecolorcolor-interpolationcursordirectiondisplaydisplaystyledominant-baselinefillfill-opacityfill-rulefont-familyfont-sizefont-size-adjustfont-stretchfont-stylefont-variantfont-weightletter-spacingmarker-endmarker-midmarker-startmathbackgroundmathcolormathsizeopacitypaint-orderpointer-eventsscriptlevelshape-renderingstop-colorstop-opacitystrokestroke-dasharraystroke-dashoffsetstroke-linecapstroke-linejoinstroke-miterlimitstroke-opacitystroke-widthtext-anchortext-decorationtext-overflowtext-renderingtransformtransform-originunicode-bidivector-effectvisibilitywhite-spaceword-spacingwriting-modecommentsdataAttributeselementsattributes list.The following table lists the MathML and SVG elements that are categorized as Default in the built-in safe default configuration, represented as a list of SanitizerElementNamespaceWithAttributes dictionaries. For each row in the table, the "Element" column corresponds to the name member, the "Namespace" column corresponds to the namespace member, and the "Allowed attributes" column corresponds to the attributes member (where each listed attribute is represented as a SanitizerAttribute in the sequence):
The built-in navigating URL attributes list corresponds to all HTML elements marked with navigating URL attributes in their normative definitions, as well as the element-attribute pairs represented in the following table. For each row in the table, the element corresponds to a SanitizerElementNamespace whose name member is given by the "Element" column and whose namespace member is given by the "Element namespace" column; and the attribute corresponds to a SanitizerAttributeNamespace whose name member is given by the "Attribute" column and whose namespace member is given by the "Attribute namespace" column:
| 要素 | Element namespace | 属性 | Attribute namespace |
|---|---|---|---|
a | SVG | href | no namespace |
a | SVG | href | XLink |
The built-in animating URL attributes list is the list of element-attribute pairs represented by the following table. For each row in the table, the element corresponds to a SanitizerElementNamespace whose name member is given by the "Element" column and whose namespace member is given by the "Element namespace" column; and the attribute corresponds to a SanitizerAttributeNamespace whose name member is given by the "Attribute" column and whose namespace member is null:
| 要素 | Element namespace | 属性 |
|---|---|---|
animate | SVG | attributeName |
animateTransform | SVG | attributeName |
設定する | SVG | attributeName |
The built-in non-replaceable elements list contains elements that must not be replaced with their children, as doing so can lead to re-parsing issues or an invalid node tree. It is the following list of SanitizerElementNamespace dictionaries, represented by the table below. For each row in the table, the "Element" column corresponds to the name member, and the "Element namespace" column corresponds to the namespace member:
| 要素 | Element namespace |
|---|---|
html | HTML |
svg | SVG |
math | MathML |
この節は非規範的である。
The Sanitizer API is intended to prevent DOM-based cross-site scripting by traversing supplied HTML content and removing elements and attributes according to a configuration. By design, the setHTML() and parseHTML() methods remove script-capable markup regardless of the configuration supplied; if any configuration could preserve such markup through these methods, that would be a bug.
However, there are security issues that the Sanitizer API cannot prevent. The following sections describe them.
この節は非規範的である。
The Sanitizer API operates solely in the DOM and adds a capability to traverse and filter an existing DocumentFragment. The Sanitizer API does not address server-side reflected or stored XSS.
この節は非規範的である。
DOM clobbering describes an attack in which malicious HTML confuses an application by using id or name attributes such that DOM properties, such as the children property of an HTML element, are shadowed by malicious content.
The Sanitizer API does not protect against DOM clobbering attacks by default, but can be configured to remove id and name attributes.
この節は非規範的である。
Script gadgets are a technique in which an attacker uses existing application code from popular JavaScript libraries to cause their own code to execute. This is often done by injecting innocent-looking code or seemingly inert DOM nodes that are only parsed and interpreted by a framework which then performs the execution of JavaScript based on that input.
The Sanitizer API cannot prevent these attacks. Instead, it relies on authors to explicitly allow unknown elements in general, and additionally to explicitly allow attributes, elements, and markup commonly used for templating and framework-specific code, such as data-* and slot attributes and elements like slot and template. These restrictions are not exhaustive and authors are encouraged to examine their third party libraries for this behavior.
この節は非規範的である。
Mutation XSS or mXSS describes an attack that exploits cases where the parsed DOM structure is not the same after serializing and parsing again, to bypass sanitization that happens before serialization. An example for carrying out such an attack is by relying on the change of parsing behavior for foreign content or mis-nested tags.
The Sanitizer API offers only functions that turn a string into a node tree. The context is supplied implicitly by all sanitizer functions: setHTML() uses the current element; Document.parseHTML() creates a new document. Therefore Sanitizer API is not directly affected by mutation XSS.
If a developer were to retrieve a sanitized node tree as a string, e.g. via innerHTML, and to then parse it again then mutation XSS can occur. This practice is strongly discouraged. If processing or passing of HTML as a string is necessary after all, then any string is to be considered untrusted and re-sanitized when inserted into the DOM. In other words, a sanitized and then serialized HTML tree can no longer be considered sanitized. A more complete treatment of mXSS can be found in [MXSS].