Вступ — Що таке DOM XSS і чому це важливо?
Уявіть, що ви відвідуєте вебсайт, якому довіряєте, і раптом ваш браузер таємно виконує шкідливий код, впроваджений атакуючим — без участі сервера цього вебсайту. Це жахлива реальність DOM-орієнтованого Cross-Site Scripting (DOM XSS), хитрий, але потужний вектор атаки, який використовує вразливості, що ховаються глибоко в JavaScript.
На відміну від традиційних атак XSS, які залежать від недоліків на стороні сервера, DOM XSS працює повністю в браузері. Він маніпулює моделлю об'єкта документа (DOM), щоб динамічно впроваджувати та виконувати шкідливі скрипти, що робить його складнішим для виявлення і навіть небезпечнішим. Для етичних хакерів і шукачів багів освоєння мистецтва виявлення та експлуатації DOM XSS може стати справжнім проривом, відкриваючи можливості для великих звітів про безпеку та цінних нагород.
У цій статті ми зануримося у світ DOM XSS, дізнаємось, як атакуючі знаходять і використовують ці вразливості, а також як ви — будь то дослідник безпеки чи розробник — можете захистити від них. Приготуйтеся, тому що це буде цікаво!
Розуміння DOM XSS — Як він відрізняється від інших типів XSS
Cross-Site Scripting (XSS) є однією з найпоширеніших вразливостей вебу, але не всі атаки XSS однакові. У той час як Stored XSS та Reflected XSS передбачають впровадження шкідливих скриптів через серверні процеси, DOM-орієнтований XSS (DOM XSS) — це атака, яка повністю відбувається на клієнтській стороні і працює виключно в браузері. Це фундаментальна відмінність, що робить DOM XSS більш прихованим, складнішим для виявлення та часто більш небезпечним.
Основні відмінності між DOM XSS і іншими типами XSS:
Контекст виконання
- Stored XSS відбувається, коли шкідливий скрипт постійно зберігається на сервері і надсилається користувачам за запитом.
- Reflected XSS відбувається, коли введення користувача обробляється сервером і миттєво відображається у відповіді.
- DOM XSS, з іншого боку, відбувається виключно в моделі документа браузера (DOM). Шкідливий payload ніколи не надсилається на сервер; натомість JavaScript динамічно обробляє його на стороні клієнта.
Вектор атаки
- Stored і reflected XSS зазвичай залежать від серверних точок ін'єкції в HTML, JavaScript або API.
- DOM XSS спрацьовує, коли клієнтський JavaScript зчитує та маніпулює ненадійними даними, такими як
document.location
,document.referrer
абоwindow.name
, і вставляє їх у небезпечний sink, наприклад,innerHTML
абоeval()
.
Складність виявлення
- Традиційні атаки XSS часто можна виявити за допомогою серверних механізмів безпеки, таких як Web Application Firewalls (WAF) або Content Security Policy (CSP).
- DOM XSS невидимий для сервера, що робить його складнішим для виявлення за допомогою звичайних журналів або інструментів безпеки. Для відстеження небезпечних змін у DOM потрібен спеціалізований динамічний аналіз.
Експлуатація в сучасних веб-додатках
- З підвищенням популярності Single Page Applications (SPA) та активного використання JavaScript у фронтендах, DOM XSS стає все більш поширеним, оскільки додатки більше покладаються на клієнтський скриптинг для динамічного рендерингу контенту.
- Багато фреймворків вводять функції безпеки, але незахищені практики програмування — такі як вставка невалідованого вводу користувача в
innerHTML
— продовжують створювати вектори атаки.
Де шукати DOM XSS у JavaScript файлах — Як визначити небезпечні джерела введення
Якщо ви хочете знайти вразливості DOM XSS, перший крок — це знати де шукати. На відміну від традиційного XSS, де вектор атаки часто видно в відповідях сервера, DOM XSS ховається на виду в JavaScript файлах.
Вразливість виникає, коли JavaScript обробляє ввід користувача ненадійним способом, змінюючи модель об'єкта документа (DOM) таким чином, що дозволяє виконувати шкідливий код.
Щоб виявити ці вразливості, нам потрібно визначити ненадійні джерела введення — місця, де дані, контрольовані користувачем, можуть потрапити в потік виконання JavaScript. Атакуючі використовують ці джерела для впровадження шкідливих payloads, що маніпулюють DOM, що веде до виконання коду в браузері жертви.
🚨 Небезпечні джерела введення в JavaScript
Найпоширенішими джерелами ненадійного введення в JavaScript-додатках є:
1 | document.URL
, document.documentURI
, та document.location
- Ці властивості містять повний URL сторінки, включаючи параметри запиту та фрагменти.
- Якщо скрипт безпосередньо впроваджує ці значення в DOM, атакуючий може створити шкідливі URL для виконання довільного JavaScript.
- Приклад уразливого коду:
var userInput = document.URL;
document.getElementById(“output”).innerHTML = userInput; // 🚨 Уразливо!
- Сценарій атаки: Користувач відвідує:
https://example.com/page?name=
Якщо JavaScript код не санітізує введення, скрипт виконується негайно.
2 | window.location.search
та window.location.hash
- Ці властивості дозволяють атакуючим впроваджувати payloads через рядки запиту або фрагменти URL.
- Приклад:
var searchQuery = window.location.search.substring(1);
document.write(searchQuery); // 🚨 Ризик DOM XSS!
- Експлуатація:
https://example.com/page.html?alert(1)
3 | document.referrer
- Ця властивість містить URL попередньої сторінки. Якщо вона впроваджується в DOM без належного санітування, її можна використовувати для виконання XSS payloads.
- Приклад:
document.write(“You came from: “ + document.referrer); // 🚨 Ризик!
4 | window.name
- Ця властивість може зберігати дані між різними сторінками і часто не помічається. Атакуючі можуть впровадити шкідливі скрипти в
window.name
і змусити додаток виконувати їх. - Приклад:
document.getElementById(“output”).innerHTML = window.name; // 🚨 Небезпечно!
5 | localStorage
та sessionStorage
- Ці API для зберігання часто використовуються для зберігання даних користувача. Якщо скрипт зчитує та впроваджує ці значення в DOM без перевірки, атакуючі можуть експлуатувати збережені payloads.
- Приклад:
document.body.innerHTML = localStorage.getItem(“userData”); // 🚨 Можна експлуатувати!
- Сценарій експлуатації: Якщо атакуючий зможе зберегти payload у
localStorage
(наприклад, через інший вектор XSS), він буде виконаний наступного разу, коли сторінка завантажиться.
🛠️ Порада: Слідуйте за потоком даних!
Знаходження DOM XSS вимагає відслідковування того, як ненадійні введення проходять через код JavaScript. Добре почати з пошуку цих джерел введення в JavaScript файлах за допомогою інструментів, таких як:
- Grep (пошук через командний рядок)
grep -rE “document\.(URL|location|referrer|cookie)” ./js_files/
- CodeQL (розширений статичний аналіз)
- Burp Suite’s DOM Invader (для динамічного тестування)
🔍 Ключові висновки
✅ DOM XSS часто ховається в JavaScript коді, що робить його складнішим для виявлення
✅ Атакуючі експлуатують джерела введення, як-от document.URL
, window.location
та localStorage
✅ Завжди відслідковуйте дані, що контролюються користувачем, від джерел введення до місць, як-от innerHTML
, document.write
та eval()
✅ Використовуйте автоматизовані інструменти та ручний аналіз для виявлення цих ризикованих патернів
У наступному розділі ми розглянемо небезпечні sink-функції JavaScript — функції, що роблять можливим DOM XSS. Залишайтеся з нами!
Небезпечні sink-функції JavaScript — Функції, що призводять до експлуатації
Знаходження вразливостей DOM XSS схоже на розв'язання головоломки. У попередньому розділі ми визначили небезпечні джерела введення — місця, де дані, контрольовані користувачем, потрапляють у додаток. Але тільки введення самі по собі не здатні викликати експлуатацію.
Щоб відбулося DOM XSS, ці ненадійні дані повинні потрапити до “sink” — функції JavaScript, яка обробляє ці дані ненадійним способом.
Уявіть це так: якщо джерела введення — це двері, що дозволяють даним користувача потрапити в додаток, то sink — це вибухівка, що чекає, щоб вибухнути, коли ці дані обробляються неналежним чином. Атакуючі маніпулюють цими sink, щоб виконати шкідливий JavaScript, що призводить до виконання коду в браузері жертви.
💣 Найнебезпечніші sink-функції JavaScript
Ось найвідоміші DOM XSS sink — функції та властивості, які можуть перетворити простий ввід на серйозну вразливість безпеки.
1️⃣ innerHTML
– Тихий вбивця
- Чому це небезпечно: Вставляє сирий HTML в елемент, виконуючи будь-який вбудований JavaScript.
✔ DOM XSS Scanner (розширення для Chrome) — Виявляє небезпечні зміни в DOM.
Стратегії пом'якшення — Як розробники можуть запобігти DOM XSS
Запобігання DOM XSS — це не просто виправлення однієї вразливості, а й впровадження безпечних практик програмування, які усувають основну причину. Ось як розробники можуть ефективно пом'якшити DOM XSS:
✅ 1. Уникайте небезпечних sink-функцій
Ніколи не використовуйте:
❌ innerHTML
, document.write()
, eval()
, setTimeout("string", time)
✔ Використовуйте безпечні альтернативи:
🔹 .textContent
замість .innerHTML
🔹 createElement()
та appendChild()
замість впровадження сирого HTML
✅ 2. Санітуйте та перевіряйте ввід користувача
Завжди санітуйте ввід користувача перед обробкою. Використовуйте бібліотеки, такі як:
- DOMPurify (для очищення ненадійного HTML)
var cleanInput = DOMPurify.sanitize(userInput);
document.getElementById("output").innerHTML = cleanInput;
✅ 3. Використовуйте безпечні API JavaScript
Замість:
element.innerHTML = userInput; // Небезпечно 🚨
Використовуйте:
element.textContent = userInput; // Безпечно ✅
Якщо потрібен HTML, використовуйте безпечні бібліотеки для шаблонів як-от React (JSX) або Mustache.js.
✅ 4. Впровадьте Політику Безпеки Контенту (CSP)
Сильна CSP допомагає запобігти виконанню вбудованих скриптів. Приклад політики:
Content-Security-Policy: default-src 'self'; script-src 'self';
Це блокує вбудовані скрипти і обмежує виконання JavaScript лише надійними джерелами.
✅ 5. Моніторинг та тестування на DOM XSS
✔ Використовуйте Burp Suite DOM Invader та Semgrep для статичного аналізу.
✔ Впроваджуйте автоматизоване тестування безпеки в CI/CD пайплайнах.
Висновок — Ключові висновки та наступні кроки для дослідників безпеки
🔹 DOM XSS є прихованим, але запобіжним — Він виникає через ненадійну обробку JavaScript, а не недоліки на стороні сервера.
🔹 Ефективне полювання за багами вимагає автоматизації та ручного тестування — Поєднуйте статичний аналіз (Semgrep, grep) і динамічне тестування (Burp Suite, DevTools) для кращих результатів.
🔹 Запобігання краще, ніж експлуатація — Розробники повинні уникати небезпечних sink, санітувати введення та впроваджувати CSP.
🔹 Будьте на крок попереду завдяки постійному навчанню — Безпека вебу еволюціонує; освоєння безпеки JS, поведінки браузерів та сучасних захистів є ключовим.
Наступні кроки? Заглибтесь у моделі безпеки браузера, досліджуйте вектори атак на стороні клієнта та вдосконалюйте свої техніки експлуатації — тому що в кібербезпеці знання є найбільшою зброєю.
Щасливого читання 🙂
Перекладено з: Extracting DOM XSS Vulnerabilities from JavaScript Files 🔥