Изменение спецификации HTML: экранирование < и > в атрибутах

Михал Бентковски
Michał Bentkowski

Опубликовано: 12 июня 2025 г.

20 мая 2025 года спецификация HTML была обновлена ​​для экранирования < и > в атрибутах, что помогло предотвратить уязвимости мутации XSS (mXSS). Это изменение появилось в Chrome 138, который был повышен до бета-версии 28 мая 2025 года и станет стабильной версией 24 июня 2025 года.

В этой статье подробно описывается влияние изменения экранирования атрибутов HTML на веб-разработчиков и возможные сбои; обоснование безопасности этого изменения объясняется в нашей соответствующей статье в блоге Security Engineering.

Что изменилось?

Предположим, что у вас есть элемент <div> , атрибут data-content которого имеет значение "<u>hello</u>" . Что происходит, когда вы читаете div.outerHTML ?

Традиционно вы бы получили следующий HTML:

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

После внесения изменений вы получите следующий HTML-код:

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

Раньше ни < ни > не экранировались в атрибутах. Теперь оба эти символа всегда экранируются.

Что не изменилось

Изменение исключительно изменяет то, как фрагменты HTML преобразуются обратно в строковое представление во время сериализации. Влияние ограничивается сценариями, где осуществляется доступ к свойствам innerHTML или outerHTML , или когда метод getHTML() вызывается для элемента. Эти операции берут существующую структуру DOM и создают текстовое представление HTML.

Это изменение не влияет на парсинг HTML. Рассмотрим следующий HTML:

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

Оба div будут проанализированы абсолютно одинаково, и в обоих случаях div.dataset.content вернет "<u>hello</u>" .

Что не сломается?

Если вы используете любой DOM API, такой как getAttribute , getAttributeNS , dataset или attributes , для извлечения значений атрибутов, они вернут те же декодированные значения, что и раньше, в частности, с декодированными < и > .

Рассмотрим следующий пример, в котором все строки console.log будут регистрировать "<u>" :

<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);

Что может сломаться?

innerHTML и outerHTML для получения атрибутов

Если вы используете innerHTML или outerHTML для извлечения значения атрибута, ваш код может сломаться. Рассмотрим следующий, хотя и немного запутанный, пример:

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

Этот код будет демонстрировать другое поведение после этого изменения. Раньше content было бы равно "<u>" , но теперь это "&lt;u&gt;" .

Обратите внимание, что парсинг HTML с помощью регулярных выражений не рекомендуется . Если вам нужно получить значение атрибута, используйте API DOM, описанные в предыдущих разделах.

Сквозные тесты

Если у вас есть конвейер CI/CD, в котором вы используете Chromium для генерации HTML, и вы написали тесты для сравнения HTML со статическим ожидаемым значением, эти тесты могут перестать работать, если какой-либо атрибут содержит < или > .

Это ожидаемая ошибка — вам необходимо обновить ожидаемое значение так, чтобы все символы < и > были заменены на &lt; и &gt;, соответственно.

Краткое содержание

В этой записи блога описывается изменение в спецификации HTML, которое заставит браузеры начать экранировать < и > в атрибутах для повышения безопасности путем предотвращения некоторых случаев мутации XSS.

Изменение будет доступно для всех пользователей 24 июня 2025 года на Chromium (версия 138) и Firefox (версия 140). Оно также включено в Safari 26 Beta, которая должна выйти около сентября 2025 года.

Если вы считаете, что это изменение нарушило работу вашего сайта, и у вас нет простого способа это исправить, сообщите об ошибке по адресу https://issues.chromium.org/ .

Дополнительная информация