Dieser Inhalt wurde automatisch aus dem Englischen übersetzt, und kann Fehler enthalten. Erfahre mehr über dieses Experiment.

View in English Always switch to English

ShadowRoot: setHTMLUnsafe() Methode

Baseline 2025
Newly available

Since ⁨September 2025⁩, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

Warnung: Diese Methode parst ihre Eingabe als HTML und schreibt das Ergebnis in das DOM. Solche APIs sind als Injection Sinks bekannt und sind potenziell ein Vektor für Cross-Site Scripting (XSS) Angriffe, wenn die Eingabe ursprünglich von einem Angreifer stammt.

Sie können dieses Risiko mindern, indem Sie immer TrustedHTML Objekte anstelle von Strings übergeben und Trusted Types erzwingen. Weitere Informationen finden Sie unter Sicherheitsüberlegungen.

Hinweis: ShadowRoot.setHTML() sollte fast immer anstelle dieser Methode verwendet werden – auf Browsern, wo dies unterstützt wird – da XSS-unsichere HTML-Entitäten immer entfernt werden.

Die setHTMLUnsafe() Methode der ShadowRoot Schnittstelle kann verwendet werden, um HTML-Eingaben in ein DocumentFragment zu parsen, wobei unerwünschte Elemente und Attribute optional gefiltert werden, um dann den bestehenden Baum im Shadow DOM zu ersetzen.

Syntax

js
setHTMLUnsafe(input) setHTMLUnsafe(input, options) 

Parameter

input

Eine Instanz von TrustedHTML oder einem String, der zu parsierendes HTML definiert.

options Optional

Ein Optionsobjekt mit den folgenden optionalen Parametern:

sanitizer Optional

Ein Sanitizer oder SanitizerConfig Objekt, das definiert, welche Elemente der Eingabe erlaubt oder entfernt werden. Dies kann auch ein String mit dem Wert "default" sein, der einen Sanitizer mit der standardmäßigen (XSS-sicheren) Konfiguration anwendet. Wenn nicht angegeben, wird kein Sanitizer verwendet.

Beachten Sie, dass im Allgemeinen ein Sanitizer effizienter erwartet wird als eine SanitizerConfig, wenn die Konfiguration wiederverwendet werden soll.

Rückgabewert

Kein (undefined).

Ausnahmen

TypeError

Dies wird geworfen, wenn:

  • input ein String übergeben wird, wenn Trusted Types durch eine CSP erzwungen werden und keine Standardrichtlinie definiert ist.
  • options.sanitizer einen der folgenden Werte übergeben wird:
    • einen Wert, der kein Sanitizer, SanitizerConfig oder String ist.
    • eine nicht normalisierte SanitizerConfig (eine, die sowohl "erlaubte" als auch "entfernte" Konfigurationseinstellungen enthält).
    • einen String, der nicht den Wert "default" hat.

Beschreibung

Die setHTMLUnsafe() Methode kann verwendet werden, um einen HTML-String zu parsen, wobei unerwünschte Elemente und Attribute optional gefiltert werden, und damit das bestehende Shadow DOM zu ersetzen.

Im Gegensatz zu ShadowRoot.innerHTML werden Deklarative Shadow Roots in der Eingabe in das DOM geparst. Wenn der HTML-String mehr als eine Deklarative Shadow Root in einem bestimmten Shadow Host definiert, wird nur die erste ShadowRoot erstellt – nachfolgende Deklarationen werden als <template> Elemente innerhalb dieser Shadow Root geparst.

setHTMLUnsafe() führt standardmäßig keine Bereinigung durch. Wenn kein Sanitizer als Parameter übergeben wird, werden alle HTML-Entitäten in der Eingabe injiziert.

Sicherheitsüberlegungen

Das Suffix "Unsafe" im Methodennamen weist darauf hin, dass es keine Entfernung aller XSS-unsicheren HTML-Entitäten erzwingt (im Gegensatz zu ShadowRoot.setHTML()). Es kann dies tun, wenn es mit einem geeigneten Sanitizer verwendet wird, es muss jedoch keinen effektiven Sanitizer verwenden oder überhaupt einen verwenden! Die Methode ist daher ein potenzieller Vektor für Cross-Site Scripting (XSS) Angriffe, bei denen potenziell unsichere Strings, die von einem Benutzer bereitgestellt werden, ohne vorherige Bereinigung in das DOM injiziert werden.

Sie sollten dieses Risiko mindern, indem Sie stets TrustedHTML Objekte anstelle von Strings übergeben, und Trusted Types erzwingen mithilfe der require-trusted-types-for CSP-Direktive. Dies stellt sicher, dass die Eingabe durch eine Transformationsfunktion geleitet wird, die die Möglichkeit hat, die Eingabe zu bereinigen, um potenziell gefährliches Markup (wie zum Beispiel <script> Elemente und Eventhandler-Attribute) zu entfernen, bevor es injiziert wird.

Die Verwendung von TrustedHTML ermöglicht es, zu auditieren und zu überprüfen, dass der Bereinigungscode nur an wenigen Stellen effektiv ist, anstatt über alle Ihre Injection Sinks verstreut zu sein. Sie sollten keinen Sanitizer an die Methode übergeben müssen, wenn Sie TrustedHTML verwenden.

Wenn Sie aus irgendeinem Grund TrustedHTML (oder noch besser, setHTML()) nicht verwenden können, ist die nächstsicherste Option, setHTMLUnsafe() mit dem standardmäßigen, XSS-sicheren Sanitizer zu verwenden.

Wann sollte setHTMLUnsafe() verwendet werden?

setHTMLUnsafe() sollte fast nie verwendet werden, wenn ShadowRoot.setHTML() verfügbar ist, da es nur sehr wenige (wenn überhaupt) Fälle gibt, in denen benutzerdefinierte HTML-Eingaben XSS-unsichere Elemente enthalten müssen. Nicht nur ist setHTML() sicher, sondern es spart auch die Überlegung über Trusted Types.

Die Verwendung von setHTMLUnsafe() könnte angemessen sein, wenn:

  • Sie setHTML() oder Trusted Types nicht verwenden können (aus welchen Gründen auch immer) und Sie die sicherste mögliche Filterung wünschen. In diesem Fall könnten Sie setHTMLUnsafe() mit dem standardmäßigen Sanitizer verwenden, um alle XSS-unsicheren Elemente herauszufiltern.

  • Sie können setHTML() nicht verwenden und die Eingabe könnte deklarative Shadow Roots enthalten, sodass Sie ShadowRoot.innerHTML nicht verwenden können.

  • Sie haben einen Sonderfall, bei dem Sie HTML-Eingaben zulassen müssen, die eine bekannte Menge unsicherer HTML-Entitäten enthalten.

    Sie können setHTML() in diesem Fall nicht verwenden, da es alle unsicheren Entitäten entfernt. Sie könnten setHTMLUnsafe() ohne einen Sanitizer oder innerHTML verwenden, dadurch würden jedoch alle unsicheren Entitäten zugelassen.

    Eine bessere Option hier ist, setHTMLUnsafe() mit einem Sanitizer aufzurufen, der nur die gefährlichen Elemente und Attribute zulässt, die wir tatsächlich benötigen. Auch wenn dies immer noch unsicher ist, ist es sicherer, als alle zuzulassen.

Für den letzten Punkt, betrachten Sie eine Situation, in der Ihr Code darauf angewiesen ist, unsichere onclick Handler verwenden zu können. Der folgende Code zeigt die Wirkung der verschiedenen Methoden und Sanitizer in diesem Fall.

js
const shadow = document.querySelector("#host").shadowRoot; const input = "<img src=x onclick=alert('onclick') onerror=alert('onerror')>"; // Safe - removes all XSS-unsafe entities. shadow.setHTML(input); // Removes no event handler attributes shadow.setHTMLUnsafe(input); shadow.innerHTML = input; // Safe - removes all XSS-unsafe entities. const configSafe = new Sanitizer(); shadow.setHTMLUnsafe(input, { sanitizer: configSafe }); // Removes all XSS-unsafe entities except `onclick` const configLessSafe = new Sanitizer(); config.allowAttribute("onclick"); shadow.setHTMLUnsafe(input, { sanitizer: configLessSafe }); 

Beispiele

setHTMLUnsafe() mit Trusted Types

Um das Risiko von XSS zu mindern, erstellen wir zuerst ein TrustedHTML Objekt aus dem String, der das HTML enthält, und übergeben dann dieses Objekt an setHTMLUnsafe(). Da Trusted Types noch nicht auf allen Browsern unterstützt werden, definieren wir das Trusted Types Tinyfill. Dies fungiert als transparenter Ersatz für die Trusted Types JavaScript API:

js
if (typeof trustedTypes === "undefined") trustedTypes = { createPolicy: (n, rules) => rules }; 

Als Nächstes erstellen wir eine TrustedTypePolicy, die eine createHTML() definiert, um einen Eingabestring in TrustedHTML Instanzen zu transformieren. Häufig verwenden Implementierungen von createHTML() eine Bibliothek wie DOMPurify, um die Eingabe wie unten gezeigt zu bereinigen:

js
const policy = trustedTypes.createPolicy("my-policy", { createHTML: (input) => DOMPurify.sanitize(input), }); 

Dann verwenden wir dieses policy Objekt, um ein TrustedHTML Objekt aus dem potenziell unsicheren Eingabestring zu erstellen:

js
// The potentially malicious string const untrustedString = "abc <script>alert(1)<" + "/script> def"; // Create a TrustedHTML instance using the policy const trustedHTML = policy.createHTML(untrustedString); 

Da wir nun trustedHTML haben, zeigt der folgende Code, wie Sie es mit setHTMLUnsafe() verwenden können. Zuerst erstellen wir die ShadowRoot, die wir anvisieren möchten. Diese könnte programmgesteuert mit Element.attachShadow() erstellt werden, aber für dieses Beispiel erstellen wir die Root deklarativ.

html
<div id="host"> <template shadowrootmode="open"> <span>A span element in the shadow DOM</span> </template> </div> 

Dann erhalten wir einen Handler für die Shadow Root vom #host Element und rufen setHTMLUnsafe() auf. Die Eingabe ist durch die Transformationsfunktion gegangen, daher übergeben wir keinen Sanitizer an die Methode.

js
const shadow = document.querySelector("#host").shadowRoot; // setHTMLUnsafe() with no sanitizer (no filtering) shadow.setHTMLUnsafe(trustedHTML); 

Verwendung von setHTMLUnsafe() ohne Trusted Types

Dieses Beispiel demonstriert den Fall, in dem wir keine Trusted Types verwenden und daher Sanitizer-Argumente übergeben werden müssen.

Der Code erstellt zuerst einen ungetrüsteten String und zeigt eine Reihe von Möglichkeiten, wie ein Sanitizer an die Methode übergeben werden kann.

js
// The potentially malicious string const untrustedString = "abc <script>alert(1)<" + "/script> def"; // Get the shadow root element const shadow = document.querySelector("#host").shadowRoot; // Define custom Sanitizer and use in setHTMLUnsafe() // This allows only elements: div, p, button, script const sanitizer1 = new Sanitizer({ elements: ["div", "p", "button", "script"], }); shadow.setHTMLUnsafe(untrustedString, { sanitizer: sanitizer1 }); // Define custom SanitizerConfig within setHTMLUnsafe() // Removes the <script> element but allows other potentially unsafe entities. shadow.setHTMLUnsafe(untrustedString, { sanitizer: { removeElements: ["script"] }, }); 

setHTMLUnsafe() Live-Beispiel

Dieses Beispiel bietet eine "Live"-Demonstration der Methode, wenn sie mit verschiedenen Sanitizern aufgerufen wird. Der Code definiert Schaltflächen, die Sie anklicken können, um einen HTML-String zu injizieren. Eine Schaltfläche injiziert das HTML ohne jegliche Bereinigung, und die zweite verwendet einen benutzerdefinierten Sanitizer, der <script> Elemente erlaubt, aber nicht andere unsichere Elemente. Der ursprüngliche String und das injizierte HTML werden protokolliert, damit Sie die Ergebnisse in jedem Fall überprüfen können.

Hinweis: Da wir zeigen möchten, wie das Sanitizer-Argument verwendet wird, injiziert der folgende Code einen String anstelle eines Trusted Types. Das sollten Sie in Produktionscode nicht tun.

HTML

Das HTML definiert zwei <button> Elemente zum Injizieren des HTMLs ohne Sanitizer und mit einem benutzerdefinierten Sanitizer (jeweils), eine weitere Schaltfläche zum Zurücksetzen des Beispiels und ein <div>, das die deklarative Shadow Root enthält.

html
<button id="buttonNoSanitizer" type="button">None</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 Neuladen-Schaltfläche.

js
const reload = document.querySelector("#reload"); reload.addEventListener("click", () => document.location.reload()); 

Dann definieren wir den Eingabestring, der in die Shadow Root injiziert werden soll, der in allen Fällen derselbe sein wird. Dieser enthält das <script> Element und den onclick Handler, die beide als XSS-unsafe angesehen werden. Wir erhalten auch die Variable shadow, die unser Handle auf die Shadow Root ist.

js
// 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> <p data-id="123">Para with <code>data-</code> attribute</p> </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 setHTMLUnsafe() ohne Übergabe eines Sanitizers setzt. Da kein Sanitizer vorhanden ist, erwarten wir, dass das injizierte HTML mit dem Eingabestring übereinstimmt.

js
const buttonNoSanitizer = document.querySelector("#buttonNoSanitizer"); buttonNoSanitizer.addEventListener("click", () => { // Set the content of the element with no sanitizer shadow.setHTMLUnsafe(unsanitizedString); // Log HTML before sanitization and after being injected logElement.textContent = "No sanitizer\n\n"; log(`\nunsanitized: ${unsanitizedString}`); log(`\n\nsanitized: ${shadow.innerHTML}`); }); 

Der nächste Klick-Handler setzt das Ziel-HTML unter Verwendung eines benutzerdefinierten Sanitizers, der nur <div>, <p> und <script> Elemente erlaubt.

js
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.setHTMLUnsafe(unsanitizedString, { sanitizer: sanitizer1 }); // Log HTML before sanitization and after being injected logElement.textContent = "Sanitizer: {elements: ['div', 'p', 'script']}\n"; log(`\n\nunsanitized: ${unsanitizedString}`); log(`\nsanitized: ${shadow.innerHTML}`); }); 

Ergebnisse

Klicken Sie auf die Schaltflächen "None" und "allowScript", um die Auswirkungen von keinem Sanitizer bzw. einem benutzerdefinierten Sanitizer zu sehen.

Wenn Sie die Schaltfläche "None" klicken, sollten Sie sehen, dass die Eingabe und Ausgabe übereinstimmen, da kein Sanitizer angewendet wird. Wenn Sie die Schaltfläche "allowScript" klicken, ist das <script> Element immer noch vorhanden, aber das <button> Element wird entfernt. Mit diesem Ansatz können Sie sicheres HTML erstellen, aber Sie sind nicht dazu gezwungen.

Spezifikationen

Specification
HTML
# dom-shadowroot-sethtmlunsafe

Browser-Kompatibilität

Siehe auch