Entwicklertools · HTML-Entity-Escaper
HTML-Entitäten ohne innerHTML dekodieren: So funktioniert ein Lookup-Table-Decoder
· Wie es funktioniert
html Sicherheit Kodierung
Der beliebte Trick, Entitäten durch Zuweisung zu innerHTML zu dekodieren, führt Ihre Eingabe durch den HTML-Parser, was genau das ist, was Sie nicht wollen. In diesem Beitrag wird der sicherere tabellenbasierte Ansatz erläutert und wie er mit benannten, dezimalen und hexadezimalen Referenzen umgeht.
Der Decoder, der ein <img onerror> ausgeführt hat – ein konkreter Fall, in dem „einfach dekodieren“ zur Skriptausführung wurde
Die übliche einzeilige Eingabe element.innerHTML = leistet mehr als nur die Dekodierung von &. Wenn die Eingabe auch <img src=x onerror=...> enthält, erstellt der Browser ein Bildelement und ein Event-Handler-Attribut. Abhängig davon, wie dieser Knoten angehängt und geladen wird, kann dies aus einer Formatierungsverknüpfung eine Skriptausführung machen. Eine eingefügte HTML-ähnliche Zeichenfolge sollte Daten bleiben, wenn die einzige Aufgabe darin besteht, Zeichenverweise aufzulösen, und nicht in einen DOM-Baum geparst werden.
Was innerHTML tatsächlich mit einem String macht – Parsen, Elementerstellung und Event-Handler-Attribute, nicht nur das Ersetzen von Entitäten
innerHTML ruft den HTML-Parser auf: Tags werden zu Knoten, Attribute erhalten Browserbedeutung und ein späteres Lesen von textContent entfernt Markup aus dem Ergebnis. Ein <strong>-Tag, das Sie als Literaleingabe beibehalten wollten, kann als Textformatierung verschwinden. Ein losgelöstes Element stellt keine allgemeine Sicherheitsgarantie dar; Code fügt diesen Teilbaum häufig erneut ein oder verwendet den resultierenden HTML-Code an anderer Stelle. Wenn Sie nicht vertrauenswürdige Eingaben anzeigen müssen, weisen Sie textContent zu und bereinigen Sie es nur, wenn Sie sich bewusst für die Darstellung von HTML entscheiden.
Der Lookup-Table-Ansatz – ein regulärer Ausdruck für &name;, &#NNN; und &#xHHH; und eine Zuordnung von Namen zu Zeichen
Der Decoder von ToolAcre verwendet einen begrenzten regulären Ausdruck, um eine Referenz der Form &name;, { oder { zu finden. Benannte Referenzen werden in einer praktischen, expliziten Tabelle nachgeschlagen, einschließlich amp, lt, gt, Anführungszeichen und gängiger Typografie. Ein unbekannter Name wird so belassen, wie er geschrieben wurde, und nicht erraten. Dieser Ansatz erstellt keine Elemente und ruft keinen HTML-Parser auf. Es ersetzt lediglich erkannte Teilzeichenfolgen in einer Zeichenfolge. Die Tabelle ist bewusst eine Teilmenge, nicht alle HTML-benannten Zeichenreferenzen.
Umgang mit numerischen Referenzen – Parsen von dezimalen und hexadezimalen Codepunkten und Konvertieren dieser in Zeichenfolgen, einschließlich astraler Zeichen
Analysieren Sie für eine numerische Referenz die Dezimalzahl nach &# oder die Hexadezimalzahl nach &#x und wandeln Sie dann den numerischen Codepunkt mit String.fromCodePoint in ein Zeichen um. Ein astraler Wert wie 0x1F600 ergibt ein Emoji und nicht zwei unabhängige druckbare Zeichen. Die Implementierung ordnet auch historische Windows-1252-Kontrollbereichswerte zu, wie dies bei Browsern der Fall ist. Null, Ersatzcodepunkte und Werte über U+10FFFF werden zu einem Ersatzzeichen. Diese explizite Fehlerbehandlung verhindert, dass eine ungültige Zahl den Decoder zum Absturz bringt.
Bearbeitetes Beispiel: Dekodierung einer Zeichenfolge, die &, © und 😀 mischt – jede Übereinstimmung wird aus der Tabelle oder der Zahl aufgelöst
Dekodieren Sie die Literaleingaben &, © und 😀: Die erste Referenz wird durch die benannte Tabelle auf & abgebildet, die Dezimalzahl 169 wird zu © und der Hexadezimalwert 1F600 wird zu 😀. Fügen Sie daneben ein rohes <img onerror="alert(1)"> ein. Der Decoder gibt diese Tag-ähnliche Sequenz als normale Zeichenfolge zurück; Es wird kein Bild erstellt und kein Ereignis ausgeführt. Wenn Sie das Ergebnis später in eine echte Seite einfügen, verwenden Sie eine sichere Textsenke, anstatt die dekodierte Zeichenfolge zu nehmen und sie innerHTML wieder zuzuweisen.
Was der Tabellenansatz nicht bewirken wird – veraltete Referenzen ohne Semikolons und Macken bei der Parser-Fehlerbehebung, es sei denn, er wird bewusst implementiert
Der Lookup-Ansatz reproduziert absichtlich nicht die alten semikolonlosen Wiederherstellungsregeln des HTML-Parsers. © ohne Semikolon bleibt möglicherweise unberührt. In der fest benannten Tabelle werden auch viele der mehr als zweitausend benannten HTML5-Referenzen weggelassen. Diese Einschränkungen sind ehrliche Kompromisse für einen kleinen, vorhersehbaren Decoder. Indem nur explizit beendete Referenzen akzeptiert werden, wird vermieden, dass willkürliche Prosa, die ein kaufmännisches Und enthält, als Markup behandelt wird. Überprüfen Sie die dokumentierten unterstützten Namen des Tools, wenn vollständige Browserkompatibilität unerlässlich ist.
Was dies nicht abdeckt – das Bereinigen von HTML, das Sie rendern möchten, was ein anderes Problem darstellt
Durch das Dekodieren von Referenzen wird HTML nicht für die Anzeige bereinigt. Wenn der dekodierte Text eine <script>-Sequenz enthält, bleibt es gefährlich, wenn ein anderer Teil einer Anwendung sie später als Markup einfügt. Kontexte wie ein HTML-Attribut, eine JavaScript-Zeichenfolge und eine URL benötigen jeweils ihre eigene Ausgabekodierung und -richtlinie. ToolAcre gibt Text zurück; Es kann ein zukünftiges unsicheres Waschbecken nicht sicher machen.
Fazit: Eingaben als Daten behandeln – wie der HTML-Entity-Escaper mit einer Nachschlagetabelle und nicht mit dem HTML-Parser dekodiert, sodass Ihre Eingaben Text bleiben
Behandeln Sie Eingaben als Daten. Der HTML-Entity-Escaper dekodiert mit einer Tabellen- und Codepunktarithmetik, nicht mit einem innerHTML-Trick, sodass Markup-ähnliche Nutzlasten im Tool inaktive Zeichen bleiben. Probieren Sie die drei Referenzen aus und überprüfen Sie dann sowohl den dekodierten Text als auch die geplante zukünftige Verwendung: Die Sicherheitsgrenze geht verloren, wenn Sie ihn als HTML erneut analysieren.