5 Punkte von GN⁺ 2026-02-26 | 2 Kommentare | Auf WhatsApp teilen
  • Um XSS-Angriffe, eine der wichtigsten Schwachstellen des Webs, zu verhindern, unterstützt Firefox als erster Browser die standardisierte Sanitizer API
  • Wird statt des bisherigen innerHTML die Methode setHTML() verwendet, wird nicht vertrauenswürdiges HTML vor dem Einfügen in das DOM automatisch bereinigt (sanitized) und bösartiges Skript entfernt
  • Wenn die Standardeinstellungen zu streng oder zu locker sind, können Entwickler über eine benutzerdefinierte Konfiguration steuern, welche Elemente und Attribute erlaubt sind
  • In Kombination mit Trusted Types hebt diese Funktion in Firefox das allgemeine Sicherheitsniveau im Web an und ermöglicht es Entwicklern, XSS auch ohne separates Sicherheitsteam zu verhindern

XSS-Schwachstellen und Firefox’ Gegenmaßnahmen

  • Cross-Site Scripting (XSS) entsteht, wenn Angreifer über von Nutzern eingegebene Inhalte beliebiges HTML oder JavaScript einschleusen können
    • Angreifer können dies nutzen, um Nutzerinteraktionen zu überwachen oder Daten zu stehlen
    • XSS wird seit fast 10 Jahren als eine der Top-3-Webschwachstellen (CWE-79) eingestuft
  • Firefox stärkt die XSS-Abwehr seit 2009, indem es den Standard Content-Security-Policy (CSP) vorantreibt
    • CSP beschränkt, welche Ressourcen eine Website laden und ausführen darf
    • Wegen nötiger Änderungen an bestehenden Website-Strukturen und fortlaufender Sicherheitsprüfungen gab es jedoch Grenzen für eine breite Einführung

Die Rolle von Sanitizer API und setHTML()

  • Die Sanitizer API bietet einen standardisierten Weg, bösartiges HTML in eine harmlose Form umzuwandeln
    • Im Codebeispiel wird das Element <img src="x" onclick="alert('XSS')"> entfernt, und nur <h1>Hello my name is</h1> bleibt übrig
  • Die Methode setHTML() führt beim Einfügen von HTML automatisch eine Bereinigung durch und gewährleistet damit ein standardmäßig sicheres Verhalten
    • Schon der Austausch einer innerHTML-Zuweisung durch setHTML() ermöglicht eine starke XSS-Abwehr
  • Falls die Standardeinstellungen zu strikt oder zu locker sind, können Entwickler über eine Custom-Konfiguration festlegen, welche HTML-Elemente und Attribute erlaubt sind
    • Für Experimente kann das Tool Sanitizer API playground genutzt werden

Kombination mit Trusted Types

  • Die Trusted Types API bietet eine zusätzliche Sicherheitsschicht, indem sie das Parsen und Einfügen von HTML zentral steuert
    • Bei der Verwendung von setHTML() lassen sich Trusted-Types-Richtlinien einfach anwenden
    • Eine strenge Richtlinie erlaubt nur setHTML() und blockiert andere riskante Einfügemethoden, was zur Vermeidung künftiger XSS-Regressionen beiträgt

Sicherheitsverbesserungen in Firefox 148

  • Firefox 148 unterstützt sowohl die Sanitizer API als auch Trusted Types und verbessert das grundlegende Sicherheitsniveau deutlich
  • Entwickler können XSS schon mit einfachen Codeänderungen verhindern, ganz ohne komplexe Sicherheitsrichtlinien oder ein separates Sicherheitsteam
  • Von der Einführung dieses Standards wird erwartet, dass sie die Verbreitung eines sichereren Webs in allen Browsern fördert

Zusammenfassung

  • Firefox 148 unterstützt Webentwickler mit der setHTML()-Methode und der Sanitizer API dabei, XSS-Angriffe einfach zu blockieren
  • Die Funktion ergänzt die Grenzen von CSP und ist ein Schritt hin zu einem standardmäßig sicheren Verfahren für das Einfügen von HTML als Webstandard
  • In Kombination mit Trusted Types werden langfristige Sicherheit und die Vermeidung von XSS-Regressionen möglich
  • Damit treibt Firefox den Wandel hin zu einem Web, in dem Sicherheit der Standard ist, voran

2 Kommentare

 
huiya 2026-02-26

Oh, so etwas braucht man auf jeden Fall. Wenn das in allen Browsern unterstützt wird, wäre das wirklich großartig.

 
GN⁺ 2026-02-26
Hacker-News-Kommentare
  • Solche Funktionen wirken immer etwas beunruhigend
    Es gibt dann eine Mischung aus Methoden, die auch mit beliebigen Benutzereingaben sicher umgehen, und solchen, die das nicht tun, aber allein am Namen ist das schwer zu erkennen
    Idealerweise sollte schon von Anfang an im Namen klar erkennbar sein, welche Funktionen gefährlich sind
    Außerdem ist das Konzept, HTML zu „sanitizen“, an sich vage, und es ist schwer zu beurteilen, ob es tatsächlich sicher ist

    • Dass die Definition von „sicher“ vage ist, stimmt, aber das Ziel hier ist XSS-sicher
      Elemente oder Attribute, mit denen sich Skripte ausführen lassen, werden entfernt, und diese Logik läuft innerhalb der Browser-Engine, wodurch sie präziser arbeitet als stringbasierte Sanitizer
      Details dazu stehen in der MDN-Dokumentation zu setHTML
    • Tatsächlich gibt es bereits eine klare Unterscheidung
      elementNode.textContent ist auch bei nicht vertrauenswürdigen Eingaben sicher, elementNode.innerHTML hingegen nicht
      Ersteres escaped alle Zeichen, Letzteres gar keine
      Manche vertreten die Ansicht, dass „HTML-Sanitization“ grundsätzlich ein unlösbares Problem ist
      Siehe dazu diesen Kommentar
      Eine solche API hätte die Vorschlagsphase gar nicht erst passieren dürfen
    • Statt innerHTML und setHTML parallel zu verwenden, hätte man innerHTML komplett entfernen und für das alte Verhalten setHTMLUnsafe anbieten sollen
    • Es wäre gut, wenn Webentwickler per globaler Einstellung veraltete APIs wie innerHTML deaktivieren könnten
      Allerdings könnte dann die Website in alten Browsern nicht mehr funktionieren
    • Wenn eine Seite mit dem Header Content-Security-Policy: require-trusted-types-for 'script' ausgeliefert wird, lässt sich verhindern, dass an Methoden ohne Sanitizer gewöhnliche Strings übergeben werden
  • Wenn man wie im Beispiel Tags wie <h1> oder <br> in einen Benutzernamen einfügen kann, ist trotz blockierter Skriptausführung weiterhin beliebige Markup-Injektion möglich
    Mit einem <style>-Tag ließe sich auch CSS verändern und etwa das Design einer PayPal-Profilseite umgestalten
    Da fragt man sich, wer so etwas wollen würde

    • Trotzdem kann das nützlich sein, wenn man Nutzern wie in einem Forum erlauben möchte, Markdown zu verwenden
      Man kann eine zusätzliche Schutzschicht einbauen, indem man das aus Markdown erzeugte HTML nochmals durch einen Sanitizer einschränkt und nur bestimmte Tags zulässt
    • In so einem Fall hätte man statt innerHTML besser innerText oder textContent verwenden sollen
      setHTML ist als Ersatz für innerHTML gedacht
    • Wenn die Standardeinstellungen von setHTML() zu streng oder zu locker sind, kann der Entwickler eine benutzerdefinierte Konfiguration bereitstellen, in der erlaubte HTML-Elemente und Attribute direkt festgelegt werden
    • Auch nur mit CSS können Sicherheitsrisiken entstehen, daher ist weiterhin Vorsicht nötig
      Siehe dazu diesen Thread
    • Zum Beispiel
      .setHTML("<h1>Hello</h1>", new Sanitizer({}))
      
      Damit werden alle Elemente entfernt
      Letztlich muss man Benutzernamen also auch im Backend weiterhin auf die übliche Weise sanitizen und bei der Ausgabe HTML-Escaping anwenden
      Laut RFC 2119 ist das eine Anforderung auf „SHOULD“-Niveau
  • Ich begrüße die Einführung dieser Funktion, aber es dürfte noch dauern, bis die Browser-Unterstützung ausreichend verbreitet ist
    Den aktuellen Stand kann man bei Can I use prüfen

    • Wie bei anderen Browser-APIs könnte es mehrere Jahre dauern, oder bei Fokus auf nur die neuesten Versionen schon in wenigen Monaten möglich sein
      In der Zwischenzeit kann man auf ein Polyfill ausweichen
  • Der Titel war etwas reißerisch
    Eigentlich ließe sich Sanitization doch auch mit einer Funktion umsetzen, die Eingaben prüft, bevor sie an innerHTML übergeben werden
    Solche Versuche fühlen sich allerdings am Ende wie eine Neuerfindung des Rads an
    Außerdem lässt sich hacks.mozilla.org in älteren Firefox-Versionen gar nicht öffnen, und in Pale Moon oder SeaMonkey wird MDN fehlerhaft dargestellt
    Es wirkt fast so, als wolle ein „Browser-Kartell“ das Web kaputtmachen

    • „Das lässt sich mit einer Eingabeprüfungsfunktion lösen“ ist ungefähr so, als würde man sagen: „Auch C ist speichersicher, solange es keine Bugs gibt“
      Dabei wird noch nicht einmal das Problem unterschiedlicher Parserinterpretationen (parser differential) berücksichtigt
  • Die Sanitizer API kann bei falscher Verwendung zu einem Footgun werden
    Besonders im „remove“-Modus ist Vorsicht geboten
    Meiner Meinung nach wäre es besser, nur setText zu verwenden und Nutzern überhaupt kein HTML zu erlauben

    • Mit einem Allowlist-basierten Sanitizer sinkt das Risiko, aber solange setHTML verwendet wird, tritt kein XSS auf
    • Aber was ist mit Fällen, in denen der Seitenautor große HTML-Fragmente einfügen muss
      Wenn man sieht, wie häufig innerHTML verwendet wird, ist ein vollständiger Verzicht schwer vorstellbar
    • So eine API könnte im Gegenteil sogar gefährlicher sein, weil sie die Illusion erzeugt, „100 % sicher“ zu sein
  • Beeindruckend ist, dass inzwischen alle Aspekte des Netzwerkzugriffs sauber kontrolliert werden und sich die Sicherheitskette damit von Vertrauen in den Code zu Vertrauen in die Host-Konfiguration verschoben hat
    Auch die Standardwerte sind sicher gesetzt

  • Was ich wirklich möchte, ist ein <sandbox>-Element, mit dem sich gefährlicher Code sicher ausführen lässt
    Nicht riskanten Code umzuschreiben, sondern ihn in einer isolierten Umgebung laufen zu lassen
    iframes haben die Einschränkung, nicht zusammen mit dem DOM zu fließen, und in einer Zeit von AI und zunehmend dynamischen Inhalten braucht es komponierbare Kapselung

  • Den Namen setHTMLUnsafe finde ich wirklich gut
    Sicherheitsfunktionen scheitern, wenn Entwickler sich bewusst dafür entscheiden müssen
    Effektiver ist es, „den gefährlichen Pfad auch gefährlich wirken zu lassen“

  • Der Name set_html() ist viel intuitiver als inner_html
    Die APIs in JavaScript sind wirklich ein ziemliches Durcheinander und müssten irgendwann aufgeräumt werden
    In dieser Diskussion geht es zwar um Sicherheit, aber auch das Design neuer APIs sollte sauber sein

    • Genau genommen ist das eine DOM-API
      DOM-APIs vermitteln seit jeher, auch heute noch, den Eindruck, als seien sie von Leuten entworfen worden, die noch nie APIs gebaut haben
  • Entwickler in den 90ern:

    SQL("select * from user where name = " + name);
    

    Entwickler in den 2020ern:

    div.innerHTML = "Hello " + user.name;
    
    • Entwickler in den 2030ern:
      "Summarize this email: " + email.contents
      
      Prompt Injection ist nur dasselbe Problem auf neuer Technologie
      Wir haben aus den 90ern nichts gelernt