Wijziging HTML-specificatie: ontsnappen aan < en > in kenmerken

Michał Bentkowski
Michał Bentkowski

Gepubliceerd: 12 juni 2025

Op 20 mei 2025 werd de HTML-specificatie bijgewerkt om < en > in kenmerken te escapen, wat helpt bij het voorkomen van mXSS- kwetsbaarheden (Mount XSS). Deze wijziging is geïmplementeerd in Chrome 138, dat op 28 mei 2025 werd gepromoveerd tot bètaversie en op 24 juni 2025 stabiel wordt.

In dit bericht wordt de impact van de wijziging in HTML-attribuut-escaping voor webontwikkelaars en mogelijke problemen beschreven. De beveiligingsredenering achter deze wijziging wordt uitgelegd in ons gerelateerde bericht op de Security Engineering-blog.

Wat is er veranderd?

Stel dat je een <div> -element hebt waarvan het attribuut data-content de waarde "<u>hello</u>" heeft. Wat gebeurt er als je div.outerHTML leest?

Vroeger kreeg je de volgende HTML:

<div data-content="<u>hello</u>"></div>

Na de wijziging ontvangt u de volgende HTML:

<div data-content="&lt;u&gt;hello&lt;/u&gt;"></div>

Voorheen werden < noch > geëscaped in attributen. Nu worden beide tekens altijd geëscaped.

Wat niet veranderde

De wijziging wijzigt uitsluitend hoe HTML-fragmenten tijdens serialisatie terug worden omgezet naar een tekenreeksrepresentatie. De impact is beperkt tot scenario's waarbij de innerHTML of outerHTML -eigenschappen worden gebruikt, of wanneer de getHTML() methode op een element wordt aangeroepen. Deze bewerkingen nemen de bestaande DOM-structuur over en produceren een tekstuele HTML-representatie.

Deze wijziging heeft geen invloed op het parsen van HTML. Bekijk de volgende HTML:

<div id="div1" data-content="<u>hello</u>"></div>
<div id="div2" data-content="&lt;u&gt;hello&lt;/u&gt;"></div>

Beide div 's worden op exact dezelfde manier geparseerd en in beide gevallen retourneert div.dataset.content "<u>hello</u>" .

Wat gaat niet kapot?

Als u een DOM API gebruikt, zoals getAttribute , getAttributeNS , dataset of attributes , om attribuutwaarden op te halen, worden dezelfde gedecodeerde waarden als hiervoor geretourneerd, met name met < en > gedecodeerd.

Overweeg het volgende voorbeeld, waarin alle console.log -regels "<u>" registreren:

<div data-content="&lt;u&gt;"></div>
const div = document.querySelector("div");
// All of the following will log "<u>"
console.log(div.getAttribute("data-content"));
console.log(div.dataset.content);
console.log(div.attributes['data-content'].value);

Wat kan kapot gaan?

innerHTML en outerHTML om attributen te verkrijgen

Als je innerHTML of outerHTML gebruikt om de waarde van een kenmerk te extraheren, kan je code kapotgaan. Beschouw het volgende, zij het ietwat ingewikkelde, voorbeeld:

<div data-content="<u>"></div>
const div = document.querySelector("div");
const content = div.outerHTML.match(/"([^"]+)"/)[1];
console.log(content);

Deze code zal na deze wijziging anders gedrag vertonen. Voorheen was content gelijk aan "<u>" maar nu is het "&lt;u&gt;" .

Houd er rekening mee dat het parsen van HTML met reguliere expressies niet wordt aanbevolen . Als u een waarde van een kenmerk nodig hebt, gebruik dan de DOM API's die in voorgaande secties zijn beschreven.

End-to-end-testen

Als u een CI/CD-pijplijn hebt waarin u Chromium gebruikt om HTML te genereren en u tests hebt geschreven om de HTML te vergelijken met een statische verwachte waarde, kunnen deze tests mislukken als een kenmerk < of > bevat.

Dit is een verwachte fout: u moet de verwachte waarde bijwerken, zodat alle < en > tekens worden omgezet naar respectievelijk &lt; en &gt;,

Samenvatting

In deze blogpost wordt een wijziging in de HTML-specificatie beschreven die ertoe zal leiden dat browsers < en > in kenmerken gaan escapen om de beveiliging te verbeteren door bepaalde gevallen van mutatie-XSS te voorkomen.

De wijziging is vanaf 24 juni 2025 voor alle gebruikers beschikbaar op Chromium (versie 138) en Firefox (versie 140). Het is ook opgenomen in Safari 26 Beta, die rond september 2025 zou moeten verschijnen.

Als u van mening bent dat deze wijziging uw website heeft beschadigd en u niet over een eenvoudige manier beschikt om dit te verhelpen, meld dan een bug op https://issues.chromium.org/ .

Aanvullende informatie