Лев Корольков
Руководитель IT-департамента EFSOL Oblako
Время чтения: 10 мин

XSS

(межсайтовый скриптинг)
XSS — уязвимость веб-приложения, при которой злоумышленник внедряет вредоносный скрипт в страницу и выполняет его в браузере пользователя.

XSS, или Cross-Site Scripting, — это класс веб-уязвимостей, при котором в страницу попадает чужой скрипт и выполняется в браузере пользователя. На практике это означает, что сайт начинает показывать не только свой код, но и код злоумышленника: например, в комментарии, профиле, поисковой строке, сообщении в чате, названии файла или параметре ссылки.

Опасность XSS в том, что атака выглядит как обычное взаимодействие с сайтом. Пользователь открывает страницу, нажимает ссылку или смотрит сообщение, а браузер выполняет JavaScript в контексте доверенного домена. Если приложение хранит сессию, персональные данные, внутренние документы или административные функции, последствия могут быть серьезными: от кражи данных до действий от имени пользователя.

Для бизнеса XSS — это не просто техническая ошибка. Уязвимость может привести к утечкам, подмене интерфейса, мошенническим операциям, потере доверия клиентов, затратам на расследование инцидента и репутационному ущербу. Особенно критичны XSS в личных кабинетах, CRM, системах онлайн-банкинга, маркетплейсах, корпоративных порталах и SaaS-продуктах.

Простое объяснение

Веб-страница состоит из HTML, стилей и скриптов. Сервер отдает браузеру код, браузер его интерпретирует и показывает пользователю интерфейс. Если приложение берет пользовательский ввод и вставляет его в страницу без безопасной обработки, то ввод может стать частью кода.

Например, пользователь написал комментарий: Привет. Сайт показывает этот текст другим людям. Но если вместо обычного текста в комментарий попадет скрипт, и сайт вставит его как HTML, браузер может выполнить этот скрипт. В этом и состоит суть XSS: данные ошибочно становятся исполняемым кодом.

Главная идея защиты от XSS: все внешние данные по умолчанию считать небезопасными и выводить их только после корректного экранирования или очистки.

Как XSS выглядит в реальном продукте

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

Другой пример — административная панель. Пользователь меняет свое имя на строку с HTML-кодом. Менеджер открывает заказ этого пользователя, и в браузере менеджера выполняется чужой скрипт. В результате злоумышленник может попытаться отправить запрос от имени менеджера, изменить настройки, вытащить данные из интерфейса или подменить отображаемую информацию.

Основные виды XSS

Вид XSSКак возникаетПочему опасен
Stored XSSВредоносный код сохраняется в базе, профиле, отзыве, тикете или сообщенииСрабатывает у многих пользователей без повторной отправки ссылки
Reflected XSSКод приходит в параметре URL или форме и сразу отражается в ответе страницыЧасто используется в фишинговых ссылках и быстрых атаках
DOM-based XSSОпасная обработка данных происходит на стороне браузера в JavaScriptМожет не быть заметен на сервере и сложнее выявляется обычным логированием

Stored XSS

Stored XSS называют хранимой XSS. Это один из наиболее рискованных вариантов, потому что вредоносный ввод сохраняется в системе и автоматически показывается другим пользователям. Источником может быть отзыв, сообщение, описание товара, имя пользователя, поле адреса, заметка в CRM, комментарий к задаче или даже название загруженного файла.

Для компании хранимая XSS особенно неприятна: атака может затронуть сразу много клиентов или сотрудников, а вредоносный код будет жить в базе, пока его не найдут и не удалят. В системах с большим количеством пользовательского контента это один из ключевых рисков.

Reflected XSS

Reflected XSS называют отраженной XSS. Она возникает, когда приложение берет значение из запроса и сразу вставляет его в страницу. Например, поисковая страница показывает фразу Вы искали: запрос пользователя. Если запрос не экранируется, злоумышленник может сформировать ссылку, в которой вместо обычного текста будет фрагмент скрипта.

Такие атаки часто требуют, чтобы пользователь перешел по подготовленной ссылке. Поэтому reflected XSS нередко комбинируют с социальной инженерией: письмами, сообщениями в мессенджерах, рекламными переходами или поддельными уведомлениями.

DOM-based XSS

DOM-based XSS возникает, когда уязвимость находится в клиентском коде. Сервер может отдавать безопасную страницу, но JavaScript на стороне браузера берет данные из адресной строки, localStorage, fragment части URL или другого источника и небезопасно вставляет их в DOM.

Этот вариант особенно актуален для современных SPA-приложений, где много логики перенесено в браузер. Ошибки могут появляться при ручной работе с innerHTML, генерации шаблонов, вставке HTML из параметров URL и использовании сторонних виджетов.

Что может сделать злоумышленник через XSS

Возможности атаки зависят от архитектуры приложения, настроек cookies, прав пользователя и защиты браузера. Но общая проблема одна: вредоносный скрипт выполняется так, будто он принадлежит доверенному сайту.

  • Подменить часть интерфейса, например форму входа, уведомление или кнопку оплаты.
  • Считать данные, которые доступны на странице: имя, email, содержимое таблиц, токены в HTML, внутренние идентификаторы.
  • Отправить запросы к приложению от имени пользователя, если браузер автоматически прикладывает сессию.
  • Переадресовать пользователя на фишинговую страницу.
  • Изменить содержимое страницы так, чтобы скрыть реальные действия или показать ложный статус.
  • Запустить цепочку атак внутри корпоративного интерфейса, если жертва имеет повышенные права.

Важно понимать: XSS не всегда означает мгновенную кражу пароля. Современные браузеры и настройки безопасности могут ограничивать часть сценариев. Но даже ограниченная XSS часто дает злоумышленнику достаточно возможностей для мошенничества, разведки, обхода пользовательского доверия и атаки на бизнес-процессы.

Типичные места появления XSS

XSS часто появляется там, где команда воспринимает данные как обычный текст, но фактически выводит их в HTML, JavaScript, атрибут, URL или шаблон. Риск повышается, если приложение быстро развивается, имеет много форм ввода и использует несколько фронтенд-библиотек.

МестоПример рискаЧто проверить
Комментарии и отзывыСкрипт сохраняется и показывается другим пользователямЭкранирование вывода, очистка HTML, модерация
ПоискЗапрос пользователя отражается на странице результатовВывод поисковой фразы как текста, а не HTML
Профиль пользователяИмя или описание профиля попадает в админкуБезопасный вывод во всех ролях интерфейса
ФайлыНазвание файла содержит опасный фрагментЭкранирование имени файла при показе
Виджеты и интеграцииСторонний код вставляет данные без контроляПроверка доверия к поставщику и ограничение прав
Письма и уведомленияHTML-шаблон письма содержит необработанные данныеШаблонизатор, экранирование, тесты

Пример уязвимой логики

Ниже упрощенный пример. Приложение берет параметр name и вставляет его в страницу как готовый HTML. Если в параметр попадет опасный фрагмент, браузер может воспринять его как код.

Страница приветствия формирует ответ так:
<p>Здравствуйте, значение_из_параметра_name</p>


Безопасная идея:
выводить значение как текст, а не как HTML

Проблема не в том, что пользователь может написать странный текст. Проблема в том, что приложение не отделяет данные от кода. Защита должна быть встроена в способ вывода: данные должны экранироваться в зависимости от контекста.

Контекст вывода имеет значение

Одна и та же строка может быть безопасной в обычном тексте и опасной в другом месте. Поэтому универсальная замена нескольких символов не всегда решает проблему. Нужно понимать, куда именно вставляются данные.

  • HTML-текст: данные выводятся между тегами, например в абзаце или ячейке таблицы.
  • HTML-атрибут: данные попадают в значение атрибута, например title или value.
  • URL: данные используются как ссылка или часть ссылки.
  • JavaScript-контекст: данные вставляются внутрь скрипта или JSON-подобной структуры.
  • CSS-контекст: данные влияют на стили и могут создавать отдельные риски.

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

Как защищаться от XSS

Защита от XSS строится слоями. Нельзя рассчитывать только на один фильтр или только на политику браузера. Надежная стратегия сочетает безопасный вывод, валидацию, ограничения на HTML, настройки cookies, Content Security Policy и регулярное тестирование.

  1. Экранировать вывод. Все пользовательские данные должны выводиться как текст, если нет явной бизнес-потребности разрешать HTML.
  2. Использовать безопасные шаблонизаторы. Современные фреймворки часто экранируют значения по умолчанию, но это легко сломать ручными вставками HTML.
  3. Ограничивать разрешенный HTML. Если пользователю нужно форматирование, применяют очистку через проверенную библиотеку и белый список тегов.
  4. Не вставлять непроверенные данные через innerHTML и похожие механизмы. Лучше использовать безопасные методы создания текстовых узлов.
  5. Настроить cookies с HttpOnly, Secure и SameSite, чтобы снизить последствия атаки.
  6. Внедрить Content Security Policy. CSP не заменяет исправление уязвимости, но может ограничить выполнение нежелательных скриптов.
  7. Проверять сторонние зависимости. Уязвимый виджет или библиотека могут создать риск даже в аккуратном приложении.
  8. Проводить code review и security testing для форм, шаблонов и новых фронтенд-компонентов.

Экранирование

Экранирование превращает специальные символы в безопасное представление. Например, символы, которые браузер мог бы воспринять как часть HTML, отображаются как обычный текст. Это базовая и наиболее важная мера против XSS.

Но экранирование должно соответствовать контексту. Для HTML-текста, атрибута, URL и JavaScript нужны разные правила. Поэтому лучше использовать проверенные инструменты платформы, а не писать собственный фильтр на несколько строк.

Очистка HTML

Иногда продукту нужно разрешить пользователям форматирование: жирный текст, списки, ссылки, цитаты. В таком случае нельзя просто принимать любой HTML. Нужна очистка: система оставляет только разрешенные теги и атрибуты, а все опасное удаляет.

Очистка должна быть серверной или как минимум подтверждаться на сервере. Клиентская проверка удобна для интерфейса, но злоумышленник может отправить запрос напрямую, минуя браузерную форму.

Content Security Policy

Content Security Policy, или CSP, — это политика безопасности, которая сообщает браузеру, откуда можно загружать скрипты, стили, изображения и другие ресурсы. Хорошо настроенная CSP может снизить ущерб от XSS, потому что запрещает выполнение inline-скриптов и загрузку кода с неизвестных доменов.

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

Ошибки, которые часто приводят к XSS

  • Считать, что валидация ввода полностью заменяет экранирование вывода.
  • Фильтровать только слово script и думать, что этого достаточно.
  • Разрешать HTML в пользовательском контенте без надежной очистки.
  • Использовать innerHTML для данных из URL, API, localStorage или пользовательских форм.
  • Отключать автоэкранирование шаблонизатора ради быстрого исправления верстки.
  • Доверять данным из внутренней CRM, потому что они якобы уже проверены.
  • Проверять только публичные страницы и забывать про админки, письма, экспорт и превью.
  • Считать, что если cookie имеет HttpOnly, то XSS больше не опасна.

Последний пункт особенно важен. HttpOnly действительно мешает JavaScript прочитать cookie напрямую. Но вредоносный скрипт все еще может взаимодействовать со страницей, отправлять запросы, менять интерфейс и использовать права текущего пользователя.

Бизнес-сценарии риска

В B2C-продуктах XSS часто бьет по клиентскому доверию. Пользователь видит поддельную форму оплаты или сообщение от имени сервиса и считает его настоящим, потому что оно находится на доверенном домене. Даже если платеж не прошел через инфраструктуру компании, клиент связывает инцидент с брендом.

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

В SaaS-продуктах особое внимание нужно уделять многоарендной архитектуре. Данные одного клиента не должны влиять на интерфейс другого клиента. XSS в общем компоненте, например в комментариях или уведомлениях, может нарушить изоляцию между организациями.

Как проверять XSS на практике

Проверка XSS должна быть частью обычного процесса разработки, а не разовой активностью перед релизом. Команда может сочетать ручное тестирование, автоматические сканеры, статический анализ, ревью шаблонов и проверку зависимостей.

  • Составить список всех мест, где пользовательский ввод отображается обратно в интерфейсе.
  • Проверить не только публичный сайт, но и админки, личные кабинеты, письма, PDF-превью и экспорт.
  • Искать ручные вставки HTML и обходы безопасных механизмов фреймворка.
  • Тестировать разные роли: обычный пользователь, менеджер, администратор, модератор.
  • Проверять данные, которые приходят из интеграций и внутренних API.
  • Добавлять регрессионные тесты после исправления найденной XSS.

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

Роль фреймворков

React, Vue, Angular, современные серверные шаблонизаторы и другие инструменты помогают снизить риск XSS, потому что по умолчанию часто экранируют текстовые значения. Но фреймворк не делает приложение автоматически безопасным.

Риск возвращается, когда разработчики используют специальные возможности для вставки сырого HTML, подключают непроверенные компоненты, обрабатывают данные вне стандартного рендера или доверяют HTML из API. Поэтому в команде должны быть правила: где разрешен HTML, кто его очищает, какие библиотеки используются и как проверяются исключения.

XSS и смежные угрозы

ТерминСвязь с XSS
CSRFXSS может помогать выполнять действия от имени пользователя, а CSRF связан с подделкой запросов
CSPПолитика браузера, которая ограничивает источники скриптов и снижает ущерб
HTML escapingБазовый способ безопасно выводить пользовательские данные
Input validationПроверка входных данных полезна, но не заменяет безопасный вывод
Session hijackingПри плохих настройках XSS может помочь злоумышленнику захватить сессию

Краткий чек-лист для команды

  • Все данные пользователя выводятся через безопасные механизмы шаблонизатора.
  • Ручная вставка HTML запрещена или проходит отдельное ревью.
  • HTML-разметка от пользователей очищается по белому списку.
  • Cookies сессии имеют HttpOnly, Secure и SameSite.
  • CSP настроена и регулярно проверяется.
  • Формы, комментарии, профили, уведомления и админки покрыты тестами.
  • После исправления XSS добавлен регрессионный тест.
  • Команда знает, что внутренние данные тоже могут быть недоверенными.

Краткий итог

XSS — это уязвимость, при которой чужой скрипт выполняется в браузере пользователя на доверенном сайте. Она возникает из-за небезопасного вывода данных, ручной вставки HTML, слабой очистки контента и ошибок в клиентском коде.

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

Связанные термины

  • CSRF
  • Content Security Policy
  • HTML escaping
  • DOM
  • Cookie
  • SameSite
  • Session hijacking
  • Input validation
  • OWASP

Частые вопросы

6 вопросов
Что такое XSS простыми словами?

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

Чем XSS опасна для бизнеса?

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

Какие бывают виды XSS?

Основные виды: stored XSS, когда код сохраняется в системе; reflected XSS, когда код отражается в ответе на запрос; DOM-based XSS, когда ошибка возникает в клиентском JavaScript.

Как защититься от XSS?

Нужно экранировать вывод, не вставлять непроверенные данные как HTML, очищать разрешенную разметку, использовать безопасные шаблонизаторы, настраивать CSP и проверять код тестами.

Достаточно ли фильтровать опасные слова?

Нет. Простые фильтры легко обходятся и часто не учитывают контекст вывода. Надежнее использовать контекстное экранирование и проверенные библиотеки очистки HTML.

Помогает ли HttpOnly против XSS?

HttpOnly снижает риск кражи cookie через JavaScript, но не устраняет XSS. Скрипт все еще может менять страницу и отправлять запросы от имени пользователя.

Была ли статья полезна?
Документ обновляется командой EFSOL. Свяжитесь с нами, если нашли неточность.
Нужна консультация?

Поможем спроектировать, развернуть и сопроводить облачную или гибридную инфраструктуру под задачи вашего бизнеса.

Ответим в течение часа в рабочее время
Заказать звонок

Оставьте свои данные для того, чтобы специалист с вами связался.

Заказать звонок

Оставьте свои данные для того, чтобы специалист с вами связался.