Sabe aquele payload clássico de mXSS, especialmente o que usava a tag <noscript> e acrescia um </noscript><img src=x onerror=alert(1)> direto no valor de um atributo, tipo alt?

<noscript><a alt="</noscript><img src onerror=alert(1)>">Hello</a></noscript>


A malandragem era que, quando o sanitizador (tipo DOMPurify) processava isso e depois serializava de volta pra string, os caracteres < e > no atributo não eram escapados. Aí, na hora que o navegador ia renderizar esse HTML "limpo", ele interpretava esses caracteres como início de novas tags, e boom, XSS!

Pois é, essa brincadeira específica acabou, ou pelo menos ficou bem mais difícil no Chrome a partir da versão M138 (que vai virar estável agora 24 de junho de 2025). O Google anunciou que a especificação do HTML mudou: agora, ao serializar um DOM para string, os caracteres < e > dentro de atributos serão automaticamente convertidos para &lt; e &gt;. Com isso, aquele </noscript> ou <img ...> dentro do atributo não vai mais ter força pra quebrar a estrutura e criar uma nova tag do nada durante a re-parse do navegador.

Isso quer dizer que o mXSS morreu? Não completamente. Ainda existem outros vetores, como os que abusam da forma como o conteúdo de certas tags (tipo <style> ou <textarea>) é serializado sem escape. Mas aquela técnica específica, que dependia da falta de escape em atributos pra injetar tags, tomou um golpe duro.

Pra evitar mXSS de vez, o ideal continua sendo usar sanitizadores que manipulam e retornam o DOM diretamente, sem essa etapa de serializar para string e depois dar innerHTML.
 
 
Back to Top