Определение простыми словами
XSS — это «подсунутый» в страницу JavaScript. Браузер видит код на легитимном домене, считает его доверенным и выполняет от лица пользователя. С этого момента злоумышленнику доступны куки, токены сессии, содержимое DOM, а в худшем случае — действия от имени жертвы: оформление заказа, смена пароля, отправка перевода. По данным OWASP Top 10 XSS многие годы остаётся одной из самых распространённых проблем веб-приложений.
Уязвимость возникает, когда пользовательский ввод попадает в HTML без экранирования. Например, поле «Имя» в комментарии вставляется как <b>{name}</b>. Если в имени окажется <script>...</script>, скрипт сохранится и сработает у каждого, кто откроет страницу — это типичный stored XSS.
Сравнение типов
| Тип | Где живёт | Пример |
|---|---|---|
| Reflected | В URL-параметре | ?q=<script> |
| Stored | В базе данных | Комментарий с тегом |
| DOM-based | В клиентском JS | innerHTML без санитайза |
| Self-XSS | В консоли браузера | Социальная инженерия |
Кейсы использования
- Угон админской сессии CMS через комментарий со скриптом, читающим document.cookie.
- Подмена формы оплаты на фишинговую с теми же логотипами и доменом.
- Кейлоггер на странице ввода пароля, отправляющий клавиши на сторонний сервер.
- Негативный сценарий: «у нас нет XSS, мы экранируем ввод» — но ввод попадает в JavaScript-контекст или в атрибут href, где правила экранирования другие. Контекст определяет способ защиты.
Технические детали
curl "https://example.com/search?q=<script>alert(1)</script>"
# заголовки защиты в Nginx
add_header Content-Security-Policy
"default-src 'self'; script-src 'self'";
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "0";
add_header Set-Cookie "session=abc; HttpOnly; Secure; SameSite=Strict";
# тестирование
npm install -g xsser
xsser -u "https://example.com/search?q=XSS"
Защита строится в три слоя: экранирование вывода в нужном контексте (htmlspecialchars в PHP, шаблонизаторы с автоэкранированием), флаг HttpOnly на сессионных cookie и строгий CSP. Смежные уязвимости описаны в карточках CSRF, SQL Injection и WAF.
🔥 Где это применяется
Частые вопросы
Чем XSS отличается от CSRF?
XSS — выполнение чужого кода в браузере жертвы. CSRF — отправка действия от имени жертвы без её согласия. Защита от них строится разными механизмами.
Спасает ли HttpOnly от XSS?
Не от самой атаки, а от кражи куки через document.cookie. Скрипт всё ещё может выполнять действия в текущей сессии и подменять интерфейс.
Зачем нужен Content-Security-Policy?
CSP запрещает выполнять inline-скрипты и загружать JS со сторонних доменов. Даже если уязвимость есть — браузер просто не запустит чужой код.