Erkenne die markup-spezifischen XSS-Vektoren und setze die nativen Abwehrmechanismen von HTML ein: sandbox, noopener und Content Security Policy.
Diese Lektion in Kodokon öffnenDer Escaping-Kontext macht den ganzen Unterschied: Ein Wert, der in einem Textknoten harmlos ist, wird in einem Attribut ausführbar. Das nicht in Anführungszeichen gesetzte Attribut ist der schlimmste Fall: Ein einziges Leerzeichen in den eingeschleusten Daten genügt, um ein neues Attribut zu erzeugen, zum Beispiel einen onmouseover-Handler. Selbst korrekt in Anführungszeichen gesetzt bleibt ein Wert in sensiblen Sinks gefährlich: href und src akzeptieren das javascript:-Schema, formaction kapert das Absenden eines Formulars, und srcdoc interpretiert seine Entities nach dem Dekodieren als HTML.
<!-- userName = x onmouseover=alert(1) -->
<img src="avatar.png" alt=x onmouseover=alert(1)>
<!-- The unquoted attribute lets a handler in -->Das sandbox-Attribut eines Iframes entzieht alle Rechte, und du gewährst sie danach einzeln wieder: allow-scripts, allow-forms, allow-popups... Ohne allow-same-origin erhält das eingebettete Dokument einen undurchsichtigen Ursprung (opaque origin): keine Cookies, kein Storage, kein Zugriff auf das übergeordnete DOM - selbst wenn es von deiner eigenen Domain ausgeliefert wird.
<iframe
src="https://widget.example.com"
sandbox="allow-scripts allow-forms"
referrerpolicy="no-referrer">
</iframe>Ein target=_blank-Link gab der geöffneten Seite historisch eine window.opener-Referenz auf deinen Tab: Sie konnte deine Seite auf einen Phishing-Klon umleiten - der als Tabnabbing bekannte Angriff. Moderne Browser wenden noopener bei target=_blank inzwischen implizit an, aber es auszuschreiben bleibt wesentlich für window.open in JavaScript und um die Absicht zu dokumentieren; füge noreferrer hinzu, um auch den Referer-Header zu unterdrücken.
<a href="https://external.example"
target="_blank"
rel="noopener noreferrer">
View the external resource
</a>Eine Content Security Policy beschränkt die Quellen ausführbaren Codes und neutralisiert die meisten XSS-Angriffe, selbst wenn die Injektion gelungen ist. Über ein <meta http-equiv>-Tag deklariert hat sie dennoch blinde Flecken: Die Direktiven frame-ancestors, report-uri und sandbox werden dort ignoriert und erfordern den HTTP-Header. Bevorzuge bei jeder Antwort neu erzeugte Nonces gegenüber Domain-Allowlists, die die Direktive strict-dynamic ohnehin überflüssig macht.
<meta http-equiv="Content-Security-Policy"
content="default-src 'self';
script-src 'self' 'nonce-r4nd0m'">allow-scripts und allow-same-origin bei einem gleichursprünglichen Iframe die Sandbox auf?rel=noopener?window.opener, um deinen Tab auf eine Phishing-Seite umzuleiten<meta http-equiv> deklariert wird?