Чек-лист разработчика
18 пунктов по материалам этой страницы — для code review и аудита. Можно скачать списком в .txt.
▶ Показать все пункты на странице
XSS — это уязвимость, при которой злоумышленник внедряет JavaScript, который выполняется в браузере пользователя.
Чтобы защититься, нужно комбинировать несколько уровней защиты: encoding, validation, sanitization и безопасные DOM API.
Главный принцип
Любые данные пользователя считаются потенциально вредоносными до момента их безопасной обработки.
Цель атаки
Найти место, где данные становятся кодом, а не текстом.
📥 Input Validation (валидация)
Валидация — это проверка данных до их обработки. Она решает: принимать или отклонять данные.
В отличие от encoding, она не "чинит" данные, а блокирует неправильные.
Что это?
Валидация — проверка входных данных на соответствие ожидаемому формату (email, число, дата, URL и т.д.).
Для чего используется?
Отсеивает явно вредоносные или некорректные данные ДО того, как они попадут в систему. Например, если поле ожидает число — отклоняем всё, что содержит теги <script>. Это первый барьер защиты.
📌 Пример: проверка email через regex, reject HTML-тегов в имени пользователя
🔄 Output Encoding (экранирование)
Преобразует данные в безопасный формат, чтобы браузер не воспринимал их как код.
HTML
< → <
URL
%HH encoding
JS
\uXXXX
CSS
\XX encoding
Что это?
Экранирование (кодирование) — замена опасных символов на их безопасные HTML-сущности или escape-последовательности.
Для чего используется?
Превращает <script>alert(1)</script> в безобидный текст <script>alert(1)</script>. Браузер показывает это как текст, а НЕ выполняет как код. Обязательно применять ПЕРЕД выводом данных в HTML, атрибуты, JavaScript, CSS, URL.
📌 Контексты: HTML body, атрибуты, JavaScript строки, CSS, URL — для каждого своё кодирование!
✅ Safe Sinks
Sink — это место, куда попадают данные. Safe sinks не выполняют код.
- • textContent
- • setAttribute
- • className
- • value
- • createTextNode
⚠️ Dangerous Sinks
Эти точки интерпретируют данные как код.
- • innerHTML
- • document.write
- • eval
- • setTimeout(string)
- • onclick handlers
🧼 HTML Sanitization
Sanitization удаляет опасный HTML (script, event handlers), но сохраняет форматирование.
let clean = DOMPurify.sanitize(dirty);
Что это?
Санитизация — очистка HTML от потенциально опасных тегов и атрибутов (например, <script>, onclick=, javascript:), но с сохранением безопасного форматирования (<b>, <i>, <a href>).
Для чего используется?
Когда пользователю РАЗРЕШЕНО вводить HTML (редакторы, комментарии с форматированием), но нужно убрать вредоносный код. Лучшая библиотека — DOMPurify. В отличие от экранирования, санитизация позволяет использовать теги, но в безопасном виде.
📌 Пример: DOMPurify.sanitize("<b>привет</b><script>alert(1)</script>") → "<b>привет</b>"
🛡️ Дополнительные защиты
ограничивает выполнение скриптов
отказ от innerHTML
HttpOnly / Secure / SameSite
защита DOM XSS
Content Security Policy (CSP)
Что: HTTP-заголовок, белый список источников загрузки ресурсов.
Зачем: Блокирует inline-скрипты и выполнение кода с недоверенных доменов. Даже если XSS есть — скрипт не выполнится.
Пример: Content-Security-Policy: script-src 'self'
Trusted Types
Что: Современный браузерный API, требующий явного создания "безопасных" строк перед передачей в dangerous sinks (innerHTML).
Зачем: Полностью исключает DOM XSS — браузер не выполнит строку, если она не прошла через TrustedTypePolicy.
Пример: const policy = trustedTypes.createPolicy(...)
Safe DOM API
Что: Использование textContent, setAttribute, createElement вместо innerHTML, insertAdjacentHTML.
Зачем: Автоматическая обработка данных как текст, не как HTML. Безопасно по умолчанию, не требует экранирования.
✅ element.textContent = userInput (безопасно!)
Флаги Cookies
Что: HttpOnly, Secure, SameSite флаги для кук.
Зачем: HttpOnly — защита от кражи сессии через XSS (JavaScript не видит куку). Secure — только по HTTPS. SameSite — защита от CSRF.
Set-Cookie: sessionId=...; HttpOnly; Secure; SameSite=Strict
Защита в глубину (Defense in Depth)
Ни один метод не даёт 100% гарантии. Комбинируйте:
1️⃣ Валидация — отклоняем плохие данные
2️⃣ Экранирование — нейтрализуем опасные символы
3️⃣ Санитизация — чистим разрешённый HTML
4️⃣ Safe API — не используем innerHTML где не нужно
5️⃣ CSP — страховка, если что-то прошло
6️⃣ Trusted Types — современная защита
7️⃣ HttpOnly — защита сессий