XSS атака: механізм, види та захист у 2026 році

XSS атака залишається однією з найпоширеніших і найнебезпечніших уразливостей веб-додатків навіть у 2026 році. Вона дозволяє зловмиснику впровадити власний JavaScript-код у сторінку, яку бачить користувач, і виконати його в контексті довіреного сайту. Браузер жертви сприймає цей код як легітимний, тому скрипт отримує доступ до cookies, localStorage, DOM і може виконувати будь-які дії від імені користувача.

За даними MITRE CWE Top 25, у 2025 році Cross-Site Scripting (CWE-79) знову очолив список найнебезпечніших слабкостей програмного забезпечення. У першій половині 2026 року XSS також залишався лідером за кількістю зареєстрованих CVE. Ця уразливість входить до категорії Injection в OWASP Top 10 і продовжує з’являтися навіть у сучасних фреймворках, якщо розробники ігнорують базові правила обробки даних.

Як XSS обходить політику same-origin

Браузери захищають користувачів політикою same-origin: скрипти з одного домену не можуть читати дані іншого. XSS атака руйнує цей бар’єр зсередини. Зловмисник змушує довірений сайт самому віддати шкідливий код. Коли браузер завантажує сторінку, він виконує впроваджений скрипт з правами цього сайту.

Механізм завжди складається з двох кроків. Спочатку додаток приймає дані від користувача (або з URL, або з форми, або з заголовків). Потім ці дані без належного кодування потрапляють у HTML-відповідь або в DOM. Якщо спеціальні символи не перетворені на HTML-сутності, браузер інтерпретує їх як код.

Класичний приклад — рядок пошуку. Користувач вводить . Сервер відображає цей рядок у результатах без екранування. Браузер бачить тег script і виконує його. Скрипт може відправити cookie на сервер атакуючого, підмінити форму входу або перенаправити жертву на фішингову сторінку.

У сучасних односторінкових додатках ситуація ускладнюється. Дані часто обробляються на клієнті через innerHTML, document.write або eval. Якщо джерело даних (location.hash, postMessage, localStorage) контролюється атакуючим, виникає DOM-based XSS, який взагалі не торкається сервера.

Три основні типи XSS: порівняльна таблиця

Фахівці виділяють три класичні форми XSS-атаки. Кожна має різний вектор доставки і різний рівень небезпеки.

Тип Де зберігається payload Хто стає жертвою Рівень небезпеки
Reflected (відображена) Тільки в HTTP-запиті Лише той, хто перейшов за спеціальним посиланням Середній
Stored (збережена) У базі даних або на сервері Усі користувачі, які відкривають сторінку Високий
DOM-based Тільки на клієнті в JavaScript Користувач, чий браузер обробив шкідливий URL Середній–високий

Дані таблиці базуються на класифікації OWASP і PortSwigger Web Security Academy. Reflected XSS потребує соціальної інженерії — жертву треба змусити натиснути посилання. Stored XSS працює пасивно: достатньо одного разу зберегти скрипт у коментарі чи профілі, і він спрацьовує для кожного відвідувача. DOM-based XSS особливо підступний, бо серверні фільтри його не бачать.

Існує також сліпа (blind) XSS — підтип збереженої. Payload потрапляє в адміністративну панель або логи, які бачать лише працівники компанії. Зловмисник не отримує миттєвого підтвердження, але може скомпрометувати акаунт з високими привілеями.

Що реально відбувається після успішної XSS атаки

Наслідки варіюються від простого спливаючого вікна до повного захоплення облікового запису. Найчастіше атакуючий краде session cookie. Якщо cookie не має прапорця HttpOnly, скрипт читає document.cookie і відправляє його на зовнішній сервер. Після цього зловмисник підставляє cookie у власний браузер і отримує повний доступ до акаунта жертви.

У 2005 році хробак Samy на MySpace продемонстрував, наскільки швидко поширюється збережена XSS. За 20 годин він інфікував понад мільйон профілів. У 2014 році подібна уразливість в TweetDeck змусила тисячі акаунтів автоматично ретвітити шкідливий пост. Британські Airways у 2018 році втратили дані платіжних карток через XSS-скрипт, впроваджений у сторінку оформлення замовлення.

Сучасні атаки часто комбінують XSS з іншими техніками. Скрипт може підмінити форму двофакторної автентифікації, перехопити токен CSRF або навіть використати WebRTC для сканування внутрішньої мережі жертви. У корпоративних додатках XSS відкриває шлях до lateral movement — переходу від звичайного користувача до адміністратора.

Поширені помилки, які відкривають двері для XSS

Більшість XSS-уразливостей з’являються не через складні архітектурні помилки, а через прості звички розробників.

  • Використання innerHTML замість textContent. Будь-який рядок, який потрапляє в innerHTML, може містити теги. textContent завжди безпечний для текстового вмісту.
  • Екранування лише на вході. Фільтрація вхідних даних важлива, але недостатня. Кодування повинно відбуватися саме в момент виведення і залежно від контексту (HTML, атрибут, JavaScript, URL, CSS).
  • Довіра до фреймворків без перевірки. React екранує дані за замовчуванням, але небезпечні API на кшталт dangerouslySetInnerHTML або неправильне використання template literals легко обходять захист.
  • Ігнорування Content-Security-Policy. Багато команд вважають, що CSP «ламає» сайт, і відмовляються від нього. Насправді правильно налаштована політика блокує виконання більшості XSS-пейлоадів навіть якщо вони потрапили на сторінку.
  • Відсутність HttpOnly і SameSite для cookies. Без цих прапорців cookie стають легкою здобиччю для будь-якого скрипта.

За моїм досвідом використання цього підходу протягом місяця на кількох проєктах середнього розміру кількість знайдених XSS зменшилася майже до нуля після впровадження обов’язкового context-aware encoding і суворого CSP.

Чек-лист захисту: від початківця до досвідченого

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

  1. Завжди кодуйте дані при виведенні. Для HTML-контексту використовуйте htmlspecialchars (PHP), html.escape (Python) або вбудовані механізми шаблонізаторів.
  2. Ніколи не вставляйте користувацькі дані безпосередньо в JavaScript-рядки. Якщо це необхідно — використовуйте JSON.stringify і окремі змінні.
  3. Увімкніть Content-Security-Policy з директивою script-src ‘self’ і nonce або hash. Уникайте ‘unsafe-inline’ і ‘unsafe-eval’.
  4. Встановіть прапорці HttpOnly, Secure і SameSite=Strict (або Lax) для всіх session-cookies.
  5. Для клієнтського коду віддавайте перевагу textContent, setAttribute і createElement замість innerHTML і document.write.
  6. Регулярно тестуйте додаток автоматичними сканерами (OWASP ZAP, Burp Suite) і ручним пошуком у всіх точках введення: форми, URL-параметри, заголовки, завантажені файли (особливо SVG).
  7. Для складних випадків, коли потрібен HTML від користувача, використовуйте перевірені бібліотеки санітизації (DOMPurify).

Після кожного пункту варто перевірити, чи не з’явилися нові місця, де дані знову потрапляють у небезпечний sink. У нашій практиці ми стикалися з випадком, коли команда виправила всі форми коментарів, але забула про адмін-панель перегляду логів — саме туди потрапив blind XSS.

Коли можна впоратися самому, а коли потрібен фахівець

Якщо ви розробляєте невеликий сайт на сучасному фреймворку і дотримуєтеся чек-листа вище, більшість ризиків можна закрити власними силами. Регулярні автоматичні сканування і code review достатні для проєктів без критичних даних.

Звертатися до зовнішніх спеціалістів з безпеки варто, коли:

  • додаток обробляє персональні дані, фінансову інформацію або працює в регульованій сфері;
  • є складні клієнтські взаємодії (SPA, WebSockets, postMessage між доменами);
  • після внутрішнього аудиту залишаються незрозумілі місця або підозра на blind XSS;
  • потрібна сертифікація або відповідність стандартам (PCI DSS, ISO 27001).

Професійний pentest зазвичай виявляє не лише XSS, а й пов’язані з ним проблеми: слабкі CSP, відсутність Trusted Types, небезпечні third-party скрипти.

Питання, які найчастіше ставлять про XSS атаку

Чи захищають сучасні браузери від XSS автоматично?
Частково. Вбудовані XSS-фільтри вже майже не використовуються, бо їх легко обійти. Основний захист — Content-Security-Policy і Trusted Types. Без них браузер виконає будь-який скрипт, який потрапив на сторінку.

Чи можна знайти XSS без спеціальних інструментів?
Так. Достатньо вручну підставити в усі поля введення і параметри URL прості пейлоади на кшталт або “>. Якщо з’являється спливаюче вікно — уразливість є.

Чим DOM-based XSS відрізняється від інших?
Payload ніколи не потрапляє на сервер. Уся атака відбувається в браузері через маніпуляції з DOM. Тому серверні WAF і фільтри його не бачать.

Чи допомагає HTTPS проти XSS?
Ні. HTTPS захищає канал передачі, але не впливає на те, як браузер інтерпретує код на сторінці.

Як перевірити, чи правильно налаштований CSP?
Відкрийте DevTools → вкладка Network або Console. Браузер покаже порушення політики. Також можна використати сервіси на кшталт report-uri.com для збору звітів про порушення.

XSS атака не зникає, бо розробка веб-додатків стає все складнішою, а точки введення даних — все численнішими. Єдиний надійний спосіб залишатися захищеним — ставитися до будь-яких зовнішніх даних як до потенційно шкідливих і застосовувати кодування саме в момент виведення. Цей підхід працює і в 2005, і в 2026 році.

Денис Романенко

Денис Романенко

Київський IT-інженер. Почав з OS/2 у кінці 90-х, сидів на os2.kiev.ua, портував софт. Пізніше перейшов на Linux. Зараз DevOps/SRE: Kubernetes, безпека, VPN, автоматизація. Блог samm.kiev.ua веде з 2026-го — без хайпу, тільки те, що сам перевірив руками. Пише рідко, але по суті. Живе в Києві. Багато кави, мало сну, термінал майже завжди відкритий.

Leave a Reply

Your email address will not be published. Required fields are marked *