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/.