Back

Первый взгляд на HTML Sanitizer API

Первый взгляд на HTML Sanitizer API

Если вы когда-либо использовали innerHTML для рендеринга пользовательского контента, вы принимали определённый уровень XSS-риска. Обычное решение — подключить библиотеку вроде DOMPurify для предварительной санитизации строки. Это работает, но означает отправку дополнительного JavaScript и доверие третьей стороне в отслеживании эволюционирующего поведения парсера браузера. HTML Sanitizer API — это ответ браузера на эту проблему, и его стоит понять уже сейчас, даже если он ещё не готов к повсеместному использованию в продакшене.

Ключевые выводы

  • innerHTML парсит и внедряет разметку без каких-либо проверок безопасности, что делает его постоянным вектором XSS при работе с пользовательским контентом.
  • HTML Sanitizer API предоставляет безопасные методы, такие как Element.setHTML(), которые автоматически удаляют скрипты, обработчики событий и опасные URL перед вставкой контента в DOM.
  • Вы можете настроить Sanitizer с помощью списков разрешённых или удаляемых элементов, чтобы точно контролировать, какие элементы и атрибуты переживут санитизацию.
  • Поддержка браузерами всё ещё ограничена по состоянию на начало 2026 года, поэтому продакшен-код должен использовать определение возможностей и откатываться на DOMPurify.

Почему innerHTML всегда был риском

innerHTML делает именно то, что вы просите: парсит строку и внедряет результат в DOM без лишних вопросов. Это удобно до тех пор, пока кто-то не передаст <img src=x onerror="stealCookies()"> в качестве комментария или имени пользователя.

Библиотеки вроде DOMPurify решают эту проблему, самостоятельно парсируя строку, обходя полученное DOM-дерево и удаляя всё опасное, прежде чем вернуть вам результат. Это эффективно, но хрупко. Поведение парсера браузера меняется со временем, и библиотека, живущая в пользовательском пространстве, должна постоянно отслеживать эти изменения. Сам браузер, напротив, всегда точно знает, как он будет парсить и выполнять данный фрагмент разметки.

Что предоставляет HTML Sanitizer API

Нативный HTML Sanitizer API переносит санитизацию в браузер. Вместо прямой установки innerHTML вы используете новые методы, которые парсят, санитизируют и внедряют за один шаг.

Безопасные методы — это те, к которым вы будете обращаться чаще всего:

  • Element.setHTML()
  • ShadowRoot.setHTML()
  • Document.parseHTML()

Они всегда удаляют XSS-небезопасный контент — теги <script>, атрибуты обработчиков событий вроде onclick, javascript: URL в навигационных атрибутах — независимо от переданной конфигурации. Без какой-либо конфигурации setHTML() по сути является прямой заменой innerHTML с автоматической защитой от XSS:

const userContent = `<p>Hello!</p><script>alert('xss')<\/script>`;
document.getElementById("output").setHTML(userContent);
// Рендерится: <p>Hello!</p>
// <script> молча удаляется

Небезопасные методыsetHTMLUnsafe(), ShadowRoot.setHTMLUnsafe() и Document.parseHTMLUnsafe() — дают вам больше контроля. Они применяют только ту конфигурацию санитайзера, которую вы предоставляете, без обеспечения базовой XSS-безопасности. Используйте их только когда у вас есть конкретная причина разрешить элементы или атрибуты, которые безопасные методы заблокировали бы, и только с тщательно продуманной конфигурацией.

Настройка Sanitizer

Обе группы методов принимают опциональный экземпляр Sanitizer или словарь конфигурации. Вы можете создать allow-конфигурацию (указать точно, что разрешено, удалить всё остальное) или remove-конфигурацию (указать, что удалить, разрешить всё остальное).

Allow-конфигурация обычно является более безопасным выбором:

const sanitizer = new Sanitizer({
  elements: ["p", "b", "em", "a"],
  attributes: ["href"]
});

document.getElementById("comments").setHTML(untrustedInput, { sanitizer });

Класс Sanitizer также предоставляет методы вроде allowElement() и removeElement() для программного изменения конфигураций с сохранением их внутренней согласованности.

Поддержка браузерами и что с этим делать

Вот честная картина: по состоянию на начало 2026 года HTML Sanitizer API только начал появляться в браузерах. Firefox 148 добавил поддержку, Chrome 146 последовал за ним, но широкая кросс-браузерная доступность всё ещё догоняет. Он пока не является частью базовой веб-платформы (Baseline), что означает, что вы не можете полагаться на его доступность для всех ваших пользователей сегодня. Вы можете следить за текущей поддержкой на Can I Use.

Для продакшен-кода используйте определение возможностей и откатывайтесь на DOMPurify:

if (typeof Element.prototype.setHTML === "function") {
  element.setHTML(untrustedHTML);
} else {
  element.innerHTML = DOMPurify.sanitize(untrustedHTML);
}

Заключение

HTML Sanitizer API представляет собой именно то, что должны делать браузерные стандарты: взять опасный, широко неправильно используемый паттерн и сделать безопасный путь лёгким путём. setHTML() против innerHTML пока не является реальной дискуссией — поддержка браузерами принимает это решение за вас. Но понимание API сейчас означает, что вы будете готовы внедрить его по мере расширения поддержки, и у вас будет более чёткое представление о том, для чего на самом деле предназначена нативная HTML-санитизация браузера.

Часто задаваемые вопросы

Не надёжно. По состоянию на начало 2026 года Firefox и Chrome выпустили поддержку, но API всё ещё является функцией с ограниченной доступностью и не входит в базовую веб-платформу. Для продакшен-приложений используйте определение возможностей для проверки Element.prototype.setHTML и откатывайтесь на библиотеку вроде DOMPurify, когда API недоступен. Это даёт вам нативную санитизацию там, где она поддерживается, сохраняя безопасность везде.

setHTML всегда обеспечивает базовую XSS-безопасную политику. Он удаляет теги скриптов, атрибуты обработчиков событий и опасные URL независимо от вашей конфигурации. setHTMLUnsafe применяет только ту конфигурацию санитайзера, которую вы предоставляете, без этой страховочной сетки. Используйте setHTMLUnsafe только когда вам явно нужно разрешить элементы или атрибуты, которые безопасный метод заблокировал бы.

Пока нет. DOMPurify остаётся необходимым в качестве запасного варианта для браузеров, которым не хватает поддержки Sanitizer API. Даже когда покрытие браузерами станет универсальным, DOMPurify предлагает более детальные опции конфигурации, которые могут понадобиться некоторым проектам. Со временем, однако, нативный API должен обрабатывать большинство случаев использования санитизации без необходимости в сторонней зависимости.

Allow-конфигурация указывает точно, какие элементы и атрибуты разрешены, и удаляет всё остальное. Remove-конфигурация указывает, что удалить, и разрешает всё, что не указано явно. Allow-конфигурации обычно безопаснее, потому что они по умолчанию блокируют неизвестные или новые элементы, а не случайно разрешают их.

Complete picture for complete understanding

Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.

Check our GitHub repo and join the thousands of developers in our community.

OpenReplay