Гид по технологиям

Защита от XSS в Node.js

6 min read Безопасность Обновлено 09 Jan 2026
Защита от XSS в Node.js: руководство
Защита от XSS в Node.js: руководство

Крупный план клавиш клавиатуры с надписью HTTP

Cross-site scripting (XSS) — это тип уязвимости, при котором атакующий внедряет вредоносные скрипты в веб‑страницы, исполняющиеся в браузере клиента. Такие скрипты могут выдавать себя за легитимный код страницы, похищать сессии, куки, изменять содержимое страницы или запускать действия от имени пользователя.

Важно: в 2021 году XSS занимал вторую позицию в списке самых опасных уязвимостей (Common Weakness Enumeration — Top 25). Если вы создаёте веб‑приложения, знание XSS и способов защиты — обязательное требование.

Что такое политика одного происхождения и как XSS её обходит

Политика одного происхождения (Same‑Origin Policy, SOP) ограничивает возможность одного происхождения (origin) читать или записывать данные другого. Браузеры применяют SOP для предотвращения кражи данных между сайтами.

XSS — это попытка обмануть браузер: внедрённый скрипт выглядит как часть целевой страницы, поэтому браузер исполняет его с правами той же origin. В результате атакующий может получить токены сессии, куки и другие защищённые данные.

Типы XSS:

  • Reflected XSS — вредоносный ввод отправляется в запросе и немедленно отражается в ответе (часто в ссылках, параметрах GET/POST).
  • Stored XSS — вредоносный код сохраняется на сервере (в базе данных, комментариях) и затем отдаётся многим пользователям.
  • DOM‑based XSS — уязвимость в манипуляциях с DOM на стороне клиента (неправильная обработка location, innerHTML и т.п.).

Базовые меры защиты в Node.js

Ни одна мера не даёт 100% гарантии — применяйте комбинацию методов.

Санитизация и экранирование ввода

Санитизация (sanitization) — удаление или преобразование опасных символов. Экранирование (escaping) — преобразование символов в безопасные сущности при выводе (например, ‘<’ → ‘<’).

Разработчик обязан считать любой вход от пользователя — недоверенным. Если приложение принимает данные и потом отображает их в HTML, обязательно экранируйте их на выходе.

Пример с пакетом validator (как в исходном примере):

import validator from "validator";  
let userInput = `Jane `;  
let sanitizedInput = validator.escape(userInput);

После выполнения получится:

Jane <script onload="alert('XSS hack');"></script>

Важно: экранирование применяют при выводе в HTML. Санитизация на входе полезна, но не заменяет экранирование при выводе.

Ограничение формата вводимых данных

Проверяйте тип и формат данных: если поле должно содержать email — проверяйте его регулярным выражением или через валидатор. Для чисел используйте явное приведение и диапазоны. Чем более строгое правило, тем меньше поверхность атаки.

HTTP only cookie

Флаг httpOnly у cookie запрещает доступ из JavaScript (document.cookie). Установка флага уменьшает риск кражи сессионных куки через XSS.

Пример для Express (как в исходном тексте):

app.use(express.session({  
    secret: "secret",  
    cookie: {  
        httpOnly: true,  
        secure: true  
    }  
}))  

Если cookie помечена httpOnly, попытка читать её через JavaScript вернёт пустую строку.

Content Security Policy (CSP)

CSP ограничивает источники, с которых можно загружать скрипты, стили, изображения и т.д. Правильно настроенная политика может нейтрализовать многие XSS‑атаки, запрещая inline‑скрипты и загрузку скриптов с внешних сайтов.

Пример простого заголовка CSP:

Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self';

Примечание: CSP сложно полностью настроить для существующих приложений с большим количеством внешних скриптов — внедряйте постепенно.

Минимизируйте использование innerHTML и eval

Методы вроде element.innerHTML, document.write, eval, new Function — расширяют риск внедрения и исполнения непроверенного кода. По возможности используйте безопасные DOM‑API и шаблонизаторы, которые автоматически экранируют данные.

Защититесь на уровне шаблонизатора

Современные шаблонизаторы (Pug, EJS, Handlebars, React JSX) умеют автоматически экранировать переменные при вставке в HTML. Убедитесь, что вы не отключаете эту защиту (например, не используете «raw» вставки без нужды).

Когда базовые меры не сработают — типичные причины провалов

  • Экранирование применяется не ко всем контекстам (HTML, атрибуты, URL, JavaScript внутри атрибутов). Каждый контекст требует отдельного подхода.
  • Неправильная или неполная CSP (например, разрешён ‘unsafe-inline’).
  • Хранение HTML, введённого пользователем, без чистки (stored XSS).
  • DOM‑парсинг данных из location.hash/innerHTML без фильтрации (DOM XSS).

Практическая мини‑методология для команды разработки

  1. Принять правило: всё, что приходит от клиента — недоверенно.
  2. Валидировать формат на входе (чёткие схемы: Joi, Zod, Yup).
  3. На выходе — экранирование в зависимости от контекста (html, attr, url).
  4. Установить заголовки безопасности: CSP, X-Content-Type-Options, X-Frame-Options, Referrer-Policy.
  5. Пометить cookie как httpOnly, secure и SameSite.
  6. Проводить автоматические сканирования и ручное тестирование (DAST, pentest).

Чек‑лист по ролям

  • Разработчик:

    • Валидация и экранирование данных.
    • Не использовать innerHTML без необходимости.
    • Писать юнит‑тесты на ввод/вывод.
  • DevOps / Инфраструктура:

    • Настройка заголовков безопасности на уровне прокси/серверов (Nginx, CDN).
    • Обновление зависимостей и контроль сборок.
  • Команда безопасности:

    • Регулярные DAST/pen‑test тесты.
    • Code review фрагментов, работающих с HTML/JS.

Мини‑плейбук на случай инцидента XSS

  1. Идентификация: зафиксировать URL, payload, время и затронутых пользователей.
  2. Изоляция: при необходимости вывести сайт в режим ограниченного доступа.
  3. Устранение: удалить вредоносный контент, закрыть уязвимый эндпоинт или шаблон.
  4. Восстановление: откатить изменения, если уместно, и деплой исправления.
  5. Анализ: определить корневую причину и обновить тесты/процессы.

Критерии приёмки:

  • Все входные данные проходят валидацию и экранирование.
  • CSP настроена и не содержит ‘unsafe-inline’ в продакшене.
  • Cookie имеют httpOnly и secure флаги.
  • Автоматические тесты покрывают рефлекторные и хранимые сценарии XSS.

Дополнительные инструменты и альтернативные подходы

  • Библиотеки для санитизации: DOMPurify (клиентская), sanitize-html (Node).
  • Схемы валидации: Joi, Zod, Yup.
  • Автоматические сканеры: OWASP ZAP, Burp Suite (DAST).
  • CSP мониторинг: включать report‑uri/report‑to для тестирования политик до их ужёсточения.

Примеры кода и шаблоны

Проверка email с validator:

import validator from "validator";
if (!validator.isEmail(inputEmail)) {
  throw new Error('Invalid email');
}

Экран карты при выводе на шаблоне (Node + шаблонизатор или серверный рендеринг) — всегда использовать экранирование:

// Пример: в шаблонизаторе выводить как {{ userComment }} а не {{{ userComment }}}

Безопасность и конфиденциальность (GDPR)

XSS может привести к утечке персональных данных. Если приложение обрабатывает персональные данные, добавьте в план реагирования уведомления и оценку воздействия. Убедитесь, что журналы инцидентов хранятся безопасно.

Итог и рекомендации

Важно применять многоуровневую стратегию: валидация на входе, экранирование при выводе, настройка заголовков безопасности и ограничение возможностей выполнения динамического HTML/JS. Регулярно тестируйте приложение сканерами и вручную — и обновляйте зависимости.

Факт‑бокс:

  • XSS остаётся одной из наиболее распространённых и опасных веб‑уязвимостей.
  • Защитные уровни: входная валидация → экранирование → CSP/заголовки → безопасные шаблонизаторы → мониторинг.

Важно: никакая отдельная мера не заменяет комплексного подхода.

Краткое резюме:

  • Всегда рассматривайте ввод как недоверенный.
  • Экранируйте данные при выводе в зависимости от контекста.
  • Используйте httpOnly cookie, CSP и современные шаблонизаторы.
  • Тестируйте и документируйте проверки.
Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

RDP: полный гид по настройке и безопасности
Инфраструктура

RDP: полный гид по настройке и безопасности

Android как клавиатура и трекпад для Windows
Гайды

Android как клавиатура и трекпад для Windows

Советы и приёмы для работы с PDF
Документы

Советы и приёмы для работы с PDF

Calibration в Lightroom Classic: как и когда использовать
Фото

Calibration в Lightroom Classic: как и когда использовать

Отключить Siri Suggestions на iPhone
iOS

Отключить Siri Suggestions на iPhone

Рисование таблиц в Microsoft Word — руководство
Office

Рисование таблиц в Microsoft Word — руководство