Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions files/en-us/web/api/element/sethtml/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,32 @@ It should also be used instead of {{domxref("Element.setHTMLUnsafe()")}}, unless

Note that since this method always sanitizes input strings of XSS-unsafe entities, it is not secured or validated using the [Trusted Types API](/en-US/docs/Web/API/Trusted_Types_API).

### Re-parsing and mutated XSS (mXSS)

Even after sanitizing HTML input with `setHTML()`, it is still not safe to serialize the HTML and re-parse it using `innerHTML`.
For example, the following code is unsafe.

```js example-bad
div.setHTML(unsafeString); // Safe
const serializedHTML = div.innerHTML; // No longer sanitized!
other_element.innerHTML = serializedHTML;
```

The reason for this is that sanitization is context-aware.
When you call `setHTML()` on a particular element, the unsafe elements and attributes for that context are removed.
If you serialize the HTML and use it directly in another element, it may still contain elements that are unsafe in that element.

This would be safe (if pointless):

```js example-good
div.setHTML(unsafeString); // Safe
const serializedHTML = div.innerHTML; // Serialized as a plain string
other_div.setHTML(serializedHTML); // Safe — re-sanitized by setHTML()
```

There is a class of attacks that take advantage of this flaw, referred to as [mutated XSS](https://wicg.github.io/sanitizer-api/#mutated-xss).
The simple rule to avoid this problem is to only ever inject HTML strings using safe methods such as `setHTML()`.

## Examples

### Basic usage
Expand Down
Loading