ShadowRoot: setHTML() Methode
Die setHTML()
-Methode des ShadowRoot
-Interfaces bietet eine XSS-sichere Methode, um einen HTML-String in ein DocumentFragment
zu parsen und zu sanitieren, welches dann den bestehenden Baum im Shadow DOM ersetzt.
Syntax
setHTML(input)
setHTML(input, options)
Parameter
input
-
Ein String, der HTML definiert, das saniert und in die Shadow-Root eingefügt werden soll.
options
Optional-
Ein Optionsobjekt mit den folgenden optionalen Parametern:
sanitizer
-
Ein
Sanitizer
- oderSanitizerConfig
-Objekt, das definiert, welche Elemente des Inputs erlaubt oder entfernt werden, oder der String"default"
für die Standard-Sanitizer-Konfiguration. Beachten Sie, dass in der Regel ein"Sanitizer"
effizienter sein sollte als eineSanitizerConfig
, wenn die Konfiguration wiederverwendet werden soll. Wenn nicht angegeben, wird die Standard-Sanitizer-Konfiguration verwendet.
Rückgabewert
Keiner (undefined
).
Ausnahmen
TypeError
-
Dies wird ausgelöst, wenn
options.sanitizer
übergeben wird:- eine nicht normalisierte
SanitizerConfig
(eine, die sowohl "erlaubte" als auch "entfernte" Konfigurationseinstellungen enthält). - ein String, der nicht den Wert
"default"
hat. - ein Wert, der weder ein
Sanitizer
,SanitizerConfig
noch ein String ist.
- eine nicht normalisierte
Beschreibung
Die setHTML()
-Methode bietet eine XSS-sichere Methode, um einen HTML-String zu parsen und zu sanitieren und ihn zu verwenden, um den bestehenden Baum im Shadow DOM zu ersetzen.
setHTML()
entfernt alle HTML-Entities, die von der Sanitizer-Konfiguration nicht erlaubt sind, und entfernt außerdem alle XSS-unsicheren Elemente oder Attribute, unabhängig davon, ob sie von der Sanitizer-Konfiguration erlaubt sind.
Wenn keine Sanitizer-Konfiguration im Parameter options.sanitizer
angegeben ist, wird setHTML()
mit der Standard-Sanitizer
-Konfiguration verwendet.
Diese Konfiguration erlaubt alle Elemente und Attribute, die als XSS-sicher gelten, und verbietet dadurch Entitäten, die als unsicher angesehen werden.
Ein benutzerdefinierter Sanitizer oder eine benutzerdefinierte Sanitizer-Konfiguration kann angegeben werden, um auszuwählen, welche Elemente, Attribute und Kommentare erlaubt oder entfernt werden sollen.
Beachten Sie, dass selbst wenn unsichere Optionen durch die Sanitizer-Konfiguration erlaubt sind, sie bei Verwendung dieser Methode dennoch entfernt werden (was implizit Sanitizer.removeUnsafe()
aufruft).
setHTML()
sollte anstelle von ShadowRoot.innerHTML
verwendet werden, um unzuverlässige HTML-Strings in das Shadow DOM einzufügen.
Es sollte auch anstelle von ShadowRoot.setHTMLUnsafe()
verwendet werden, es sei denn, es besteht ein spezifisches Bedürfnis, unsichere Elemente und Attribute zuzulassen.
Da diese Methode immer Input-Strings von XSS-unsicheren Entitäten saniert, ist sie nicht durch die Trusted Types API gesichert oder validiert.
Beispiele
Grundlegende Nutzung
Dieses Beispiel zeigt einige der Möglichkeiten, wie Sie setHTML()
verwenden können, um einen HTML-String zu sanieren und einzufügen.
Zuerst werden wir das ShadowRoot
erstellen, das wir anvisieren möchten.
Dies könnte programmgesteuert mit Element.attachShadow()
erstellt werden, aber für dieses Beispiel werden wir die Root deklarativ erstellen.
<div id="host">
<template shadowrootmode="open">
<span>A span element in the shadow DOM</span>
</template>
</div>
Wir können einen Zugriff auf die Shadow-Root vom #host
Element wie folgt erhalten:
const shadow = document.querySelector("#host").shadowRoot;
Der untenstehende Code zeigt, wie wir setHTML()
mit einem String und verschiedenen Sanitizern aufrufen können, um das HTML in die Shadow-Root zu filtern und einzufügen.
// Define unsanitized string of HTML
const unsanitizedString = "abc <script>alert(1)<" + "/script> def";
// setHTML() with default sanitizer
shadow.setHTML(unsanitizedString);
// Define custom Sanitizer and use in setHTML()
// This allows only elements: <div>, <p>, <span> (<script> is unsafe and will be removed)
const sanitizer1 = new Sanitizer({ elements: ["div", "p", "span", "script"] });
shadow.setHTML(unsanitizedString, { sanitizer: sanitizer1 });
// Define custom SanitizerConfig within setHTML()
// This removes elements <div>, <p>, <span>, <script>, and any other unsafe elements/attributes
shadow.setHTML(unsanitizedString, {
sanitizer: { removeElements: ["div", "p", "span", "script"] },
});
setHTML()
Live-Beispiel
Dieses Beispiel bietet eine "Live"-Demonstration der Methode, wenn mit verschiedenen Sanitizern aufgerufen wird. Der Code definiert Schaltflächen, die Sie klicken können, um einen HTML-String mit einem Standard- und einem benutzerdefinierten Sanitizer zu sanieren und einzufügen. Der ursprüngliche String und das sanierte HTML werden protokolliert, sodass Sie die Ergebnisse in jedem Fall inspizieren können.
HTML
Das HTML definiert zwei <button>
-Elemente zum Anwenden verschiedener Sanitizer, eine weitere Schaltfläche zum Zurücksetzen des Beispiels und ein <div>
, das die deklarative Shadow-Root enthält.
<button id="buttonDefault" type="button">Default</button>
<button id="buttonAllowScript" type="button">allowScript</button>
<button id="reload" type="button">Reload</button>
<div id="host">
<template shadowrootmode="open">
<span>I am in the shadow DOM </span>
</template>
</div>
JavaScript
Zuerst definieren wir den Handler für die Neustart-Schaltfläche.
const reload = document.querySelector("#reload");
reload.addEventListener("click", () => document.location.reload());
Dann definieren wir den zu sanierenden String, der in allen Fällen derselbe sein wird.
Dieser enthält das <script>
-Element und den onclick
-Handler, die beide als XSS-unsicher gelten.
Wir erhalten auch die Variable shadow
, die unser Zugriff auf die Shadow-Root darstellt.
// Define unsafe string of HTML
const unsanitizedString = `
<div>
<p>Paragraph to inject into shadow DOM. <button onclick="alert('You clicked the button!')">Click me</button></p>
<script src="path/to/a/module.js" type="module"><script>
</div>
`;
const shadow = document.querySelector("#host").shadowRoot;
Als nächstes definieren wir den Klick-Handler für die Schaltfläche, die die Shadow-Root mit dem Standard-Sanitizer setzt.
Dies sollte alle unsicheren Entitäten entfernen, bevor der HTML-String eingefügt wird.
Beachten Sie, dass Sie genau sehen können, welche Elemente in den Sanitizer()
-Konstruktorbeispielen entfernt werden.
const defaultSanitizerButton = document.querySelector("#buttonDefault");
defaultSanitizerButton.addEventListener("click", () => {
// Set the content of the element using the default sanitizer
shadow.setHTML(unsanitizedString);
// Log HTML before sanitization and after being injected
logElement.textContent =
"Default sanitizer: remove <script> element and onclick attribute\n\n";
log(`\nunsanitized: ${unsanitizedString}`);
log(`\nsanitized: ${shadow.innerHTML}`);
});
Der nächste Klick-Handler setzt das Ziel-HTML mit einem benutzerdefinierten Sanitizer, der nur <div>
, <p>
und <script>
Elemente erlaubt.
Beachten Sie, dass da wir die setHTML
Methode verwenden, <script>
ebenfalls entfernt wird!
const allowScriptButton = document.querySelector("#buttonAllowScript");
allowScriptButton.addEventListener("click", () => {
// Set the content of the element using a custom sanitizer
const sanitizer1 = new Sanitizer({
elements: ["div", "p", "script"],
});
shadow.setHTML(unsanitizedString, { sanitizer: sanitizer1 });
// Log HTML before sanitization and after being injected
logElement.textContent =
"Sanitizer: {elements: ['div', 'p', 'script']}\n Script removed even though allowed\n";
log(`\nunsanitized: ${unsanitizedString}`);
log(`\nsanitized: ${shadow.innerHTML}`);
});
Ergebnisse
Klicken Sie auf die "Default" und "allowScript"-Schaltflächen, um die Auswirkungen des Standard- und benutzerdefinierten Sanitizers zu sehen.
Beachten Sie, dass, weil wir dieselbe Sanierungsmethode verwenden, in beiden Fällen das <script>
-Element und der onclick
-Handler entfernt werden, selbst wenn sie explizit vom Sanitizer erlaubt sind.
Spezifikationen
Specification |
---|
HTML Sanitizer API # dom-shadowroot-sethtml |