Pubblicato il 12 giugno 2025
Il 20 maggio 2025, la specifica HTML è stata aggiornata per eseguire l'escapismo di < e > negli attributi, contribuendo a prevenire le vulnerabilità di XSS di mutazione (mXSS). Questa modifica è stata introdotta in Chrome 138, che è stato promosso alla versione beta il 28 maggio 2025 e diventerà stabile il 24 giugno 2025.
Questo post illustra in dettaglio l'impatto della modifica della fuga di attributi HTML sugli sviluppatori web e sulle potenziali interruzioni. La motivazione alla base di questa modifica è spiegata nel nostro post correlato sul blog di Security Engineering.
Che cosa è cambiato
Supponiamo di avere un elemento <div> il cui attributo data-content ha un valore "<u>hello</u>". Cosa succede quando leggi div.outerHTML?
In passato, avresti ottenuto il seguente codice HTML:
<div data-content="<u>hello</u>"></div>
Dopo la modifica, otterrai il seguente codice HTML:
<div data-content="<u>hello</u>"></div>
In precedenza, né < né > erano codificati negli attributi. Ora entrambi questi caratteri sono sempre interpretati letteralmente.
Che cosa non è cambiato
La modifica riguarda esclusivamente il modo in cui i frammenti HTML vengono convertiti nuovamente in una rappresentazione di stringa durante la serializzazione. L'impatto è limitato agli scenari
in cui si accede alle proprietà innerHTML o outerHTML o quando viene invocato il metodo
getHTML() su un elemento. Queste operazioni prendono la struttura DOM esistente e producono una rappresentazione HTML testuale.
Questa modifica non influisce sull'analisi HTML. Considera il seguente codice HTML:
<div id="div1" data-content="<u>hello</u>"></div>
<div id="div2" data-content="<u>hello</u>"></div>
Entrambi i valori div verranno analizzati nello stesso modo e in entrambi i casi
div.dataset.content restituirà "<u>hello</u>".
Cosa non si romperà?
Se utilizzi un'API DOM, ad esempio
getAttribute,
getAttributeNS,
dataset,
o
attributes,
per recuperare i valori degli attributi, verranno restituiti gli stessi valori decodificati di
prima, in particolare con < e > decodificati.
Considera l'esempio seguente, in cui tutte le righe console.log registreranno"<u>":
<div data-content="<u>"></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);
Cosa può rompersi?
innerHTML e outerHTML per ottenere gli attributi
Se utilizzi innerHTML o outerHTML per estrarre il valore di un attributo, il codice può essere interrotto. Considera l'esempio seguente, anche se leggermente complicato:
<div data-content="<u>"></div>
const div = document.querySelector("div");
const content = div.outerHTML.match(/"([^"]+)"/)[1];
console.log(content);
Questo codice avrà un comportamento diverso dopo questa modifica. In precedenza,
content sarebbe stato uguale a "<u>", ma ora è "<u>".
Tieni presente che l'analisi del codice HTML con espressioni regolari non è consigliata. Se devi recuperare il valore di un attributo, utilizza le API DOM descritte nelle sezioni precedenti.
Test end-to-end
Se hai una pipeline CI/CD in cui utilizzi Chromium per generare HTML e hai scritto test per confrontare l'HTML con un valore previsto statico, questi test possono interrompersi se un attributo contiene < o >.
Si tratta di un errore previsto: devi aggiornare il valore previsto in modo che tutti i caratteri < e > vengano preceduti da sbarre rispettivamente per < e >,.
Riepilogo
Questo post del blog descrive una modifica alla specifica HTML che porterà i browser a iniziare a eseguire la fuga di < e > negli attributi per migliorare la sicurezza impedendo alcune istanze di XSS di mutazione.
La modifica sarà disponibile per tutti gli utenti il 24 giugno 2025 su Chromium (versione 138) e Firefox (versione 140). È inclusa anche in Safari 26 beta, che dovrebbe essere rilasciato intorno a settembre 2025.
Se ritieni che questa modifica abbia danneggiato il tuo sito web e non hai un modo semplice per correggerlo, invia un bug all'indirizzo https://issues.chromium.org/.