ShadowRoot: innerHTML-Eigenschaft
Warnung: Diese Eigenschaft parst ihre Eingabe als HTML und schreibt das Ergebnis in das DOM. APIs wie diese werden als Injection Sinks bezeichnet und können ein Angriffsvektor für Cross-Site-Scripting-Angriffe (XSS) sein, wenn die Eingabe ursprünglich von einem Angreifer stammt.
Sie können dieses Risiko verringern, indem Sie stets TrustedHTML-Objekte statt Zeichenfolgen zuweisen und Trusted Types erzwingen.
Weitere Informationen finden Sie unter Sicherheitsaspekte.
Die innerHTML-Eigenschaft der ShadowRoot-Schnittstelle liest oder setzt das HTML-Markup des DOM-Baums innerhalb des ShadowRoot.
Wert
Beim Lesen der Eigenschaft wird eine Zeichenfolge zurückgegeben, die die HTML-Serialisierung der Nachfahren des Shadow Roots enthält.
Beim Setzen akzeptiert die Eigenschaft entweder ein TrustedHTML-Objekt oder eine Zeichenfolge.
Sie parst diesen Wert als HTML und ersetzt alle Nachfahren des Elements durch das Ergebnis.
Wird die Eigenschaft auf den Wert null gesetzt, wird dieser in eine leere Zeichenfolge ("") umgewandelt. Daher ist shadowRoot.innerHTML = null gleichbedeutend mit shadowRoot.innerHTML = "".
Ausnahmen
SyntaxErrorDOMException-
Wird ausgelöst, wenn versucht wird,
innerHTMLauf eine Zeichenfolge zu setzen, die kein wohlgeformtes HTML ist. TypeError-
Wird ausgelöst, wenn die Eigenschaft auf eine Zeichenfolge gesetzt wird, während Trusted Types durch eine CSP erzwungen werden und keine Standard-Policy definiert ist.
Beschreibung
innerHTML liefert eine Serialisierung der verschachtelten DOM-Kindelemente innerhalb des Shadow Roots oder setzt HTML beziehungsweise XML, das geparst werden soll, um den DOM-Baum innerhalb des Shadow Roots zu ersetzen.
Beachten Sie, dass einige Browser die Zeichen < und > als < und > serialisieren, wenn sie in Attributwerten vorkommen (siehe Browser-Kompatibilität).
Dies soll eine mögliche Sicherheitslücke (Mutation XSS) verhindern, bei der ein Angreifer eine Eingabe erstellen kann, die eine Bereinigungsfunktion umgeht und so einen Cross-Site-Scripting-Angriff (XSS) ermöglicht.
Sicherheitsaspekte
Die Eigenschaft innerHTML ist ein möglicher Angriffsvektor für Cross-Site-Scripting-Angriffe (XSS), wenn potenziell unsichere, von Benutzern bereitgestellte Zeichenfolgen ohne vorherige Bereinigung in das DOM eingefügt werden.
Die Eigenschaft verhindert zwar, dass eingefügte <script>-Elemente ausgeführt werden, doch Angreifer können auf viele andere Arten HTML erstellen, das schädliches JavaScript ausführt.
Im folgenden Beispiel würde etwa der Code im error-Event-Handler ausgeführt, weil der src-Wert des <img>-Elements keine gültige Bild-URL ist:
const name = "<img src='x' onerror='alert(1)'>";
shadowRoot.innerHTML = name; // shows the alert
Sie können diese Risiken verringern, indem Sie stets TrustedHTML-Objekte statt Zeichenfolgen zuweisen und Trusted Types mithilfe der CSP-Direktive require-trusted-types-for erzwingen.
Dadurch wird sichergestellt, dass die Eingabe eine Transformationsfunktion durchläuft, die potenziell gefährliches Markup vor dem Einfügen entfernen kann.
Beispiele
>HTML-Inhalt eines Elements lesen
Beim Lesen von innerHTML serialisiert der User Agent die Nachfahren des Shadow Roots.
Gegeben sei folgendes HTML:
<div class="host">
<template shadowrootmode="open">
<p>My name is Joe</p>
</template>
</div>
So können Sie das Markup des Shadow Roots abrufen und protokollieren:
const shadowHost = document.querySelector("#host");
const shadowRoot = shadowHost.shadowRoot;
const contents = shadowRoot.innerHTML;
console.log(contents); // "\n <p>My name is Joe</p>\n"
innerHTML eines Shadow Roots setzen
In diesem Beispiel ersetzen wir den DOM-Baum eines Elements, indem wir seiner Eigenschaft innerHTML HTML zuweisen.
Um das XSS-Risiko zu verringern, erstellen wir zunächst aus der Zeichenfolge mit dem HTML ein TrustedHTML-Objekt und weisen dieses anschließend innerHTML zu.
Trusted Types werden noch nicht von allen Browsern unterstützt. Deshalb definieren wir zuerst das Trusted Types Tinyfill. Es dient als transparenter Ersatz für die Trusted Types JavaScript API:
if (typeof trustedTypes === "undefined")
trustedTypes = { createPolicy: (n, rules) => rules };
Als Nächstes erstellen wir eine TrustedTypePolicy, die eine Methode createHTML() definiert, um eine Eingabezeichenfolge in TrustedHTML-Instanzen umzuwandeln.
Implementierungen von createHTML() verwenden häufig eine Bibliothek wie DOMPurify, um die Eingabe wie unten gezeigt zu bereinigen:
const policy = trustedTypes.createPolicy("my-policy", {
createHTML: (input) => DOMPurify.sanitize(input),
});
Anschließend verwenden wir dieses policy-Objekt, um aus der potenziell unsicheren Eingabezeichenfolge ein TrustedHTML-Objekt zu erstellen, und weisen das Ergebnis dem Element zu:
// The potentially malicious string
const untrustedString = "<p>I might be XSS</p><img src='x' onerror='alert(1)'>";
// Create a TrustedHTML instance using the policy
const trustedHTML = policy.createHTML(untrustedString);
// Get the shadow root
const shadowHost = document.querySelector("#host");
const shadowRoot = shadowHost.shadowRoot;
// Inject the TrustedHTML (which contains a trusted string)
shadowRoot.innerHTML = trustedHTML;
Warnung:
Sie können innerHTML zwar direkt eine Zeichenfolge zuweisen, doch dies stellt ein Sicherheitsrisiko dar, wenn die einzufügende Zeichenfolge potenziell schädliche Inhalte enthalten könnte.
Spezifikationen
| Spezifikation |
|---|
| HTML> # dom-shadowroot-innerhtml> |