DOM-based XSS
DOM-based XSS (от англ. Document Object Model-based Cross-Site Scripting — межсайтовый скриптинг на основе объектной модели документа) — это разновидность уязвимости межсайтового скриптинга (XSS), при которой вредоносный код внедряется и выполняется на стороне клиента (в браузере пользователя) исключительно в результате манипуляций с DOM-деревом веб-страницы. В отличие от классических (отражённых и сохранённых) XSS-атак, серверная часть веб-приложения не участвует в генерации вредоносного содержимого: источником данных является клиентский JavaScript-код, который некорректно обрабатывает данные, полученные из ненадёжных источников (например, из URL-строки, фрагмента URL, document.referrer, window.name, localStorage или sessionStorage).
Принцип работы
DOM-based XSS возникает, когда веб-страница содержит JavaScript-код, который динамически изменяет DOM-дерево на основе данных, контролируемых злоумышленником, без предварительной санитизации или экранирования. Атака не требует отправки вредоносного кода на сервер и его последующего возврата в ответе HTTP. Вредоносный payload (например, строка <script>alert(1)</script>) передаётся через URL-параметр, хэш (#) или другой клиентский источник, после чего JavaScript-код страницы считывает его и вставляет в DOM, что приводит к выполнению скрипта в контексте безопасности текущего сайта.
Типичный сценарий атаки
- Пользователь переходит по специально сформированной ссылке, содержащей вредоносный код в параметре URL (например,
http://example.com/page.html#<script>...</script>`). - Браузер загружает легитимную страницу
page.htmlс сервера. - JavaScript-код на странице считывает значение из
window.location.hash(или другого клиентского источника) и вставляет его в DOM с помощью методов, таких какinnerHTML,document.write,document.createElementс последующим добавлением атрибутов, или через jQuery-функции типа.html(). - Браузер интерпретирует вставленный код как HTML и выполняет скрипт, который может, например, украсть куки-файлы, перенаправить пользователя на фишинговый сайт или изменить содержимое страницы.
Отличие от других типов XSS
Основные типы межсайтового скриптинга классифицируются по способу передачи вредоносного кода:
- Отражённый XSS (Reflected XSS): вредоносный код передаётся в HTTP-запросе (например, в параметре GET) и немедленно возвращается сервером в ответе, который и выполняет браузер. Сервер участвует в генерации страницы с вредоносным содержимым.
- Сохранённый XSS (Stored XSS): вредоносный код постоянно хранится на сервере (например, в базе данных, в комментариях, в профиле пользователя) и отображается всем пользователям, запрашивающим соответствующую страницу.
- DOM-based XSS: сервер не участвует в формировании вредоносного содержимого. Вся атака происходит на клиенте, когда легитимный JavaScript-код, загруженный с сервера, некорректно обрабатывает данные из клиентских источников.
Источники данных для DOM-based XSS
Злоумышленник может использовать различные клиентские источники для внедрения payload:
document.URLиdocument.documentURI— полный URL текущей страницы.window.location.href,window.location.search,window.location.hash— отдельные части URL.document.referrer— URL страницы, с которой пришёл пользователь.window.name— имя окна браузера, которое может быть установлено с другой страницы.localStorageиsessionStorage— данные, хранящиеся в браузере (если они были записаны вредоносным скриптом с другого сайта, но при условии, что атака уже произошла или данные были скомпрометированы иным способом).postMessage— сообщения, отправляемые между окнами или фреймами.
Примеры уязвимых конструкций
Наиболее распространённые JavaScript-конструкции, которые могут привести к DOM-based XSS, если в них вставляются непроверенные данные:
element.innerHTML = data;element.outerHTML = data;document.write(data);document.writeln(data);eval(data);setTimeout(data, 0);(если data — строка)setInterval(data, 0);(если data — строка)new Function(data);jQuery.html(data);jQuery.append(data);jQuery.prepend(data);
Методы защиты
Защита от DOM-based XSS требует применения мер на стороне клиента, так как сервер не может контролировать выполнение JavaScript-кода, который работает с данными из клиентских источников.
Основные принципы
- Экранирование (escaping): все данные, полученные из ненадёжных источников, должны быть экранированы перед вставкой в DOM. Для вставки текста следует использовать
textContentвместоinnerHTML, а для вставки HTML — строгую санитизацию с помощью специализированных библиотек, таких как DOMPurify. - Избегание опасных методов: не использовать
eval,innerHTML,document.writeи другие функции, интерпретирующие строки как код, если данные могут быть контролируемы пользователем. - Использование Content Security Policy (CSP): политика безопасности контента может ограничить выполнение встроенных скриптов и предотвратить атаки, даже если вредоносный код будет вставлен в DOM. Однако CSP не является полной защитой от DOM-based XSS, так как атака может использовать разрешённые источники скриптов.
- Валидация на стороне клиента: проверка входных данных на соответствие ожидаемому формату (например, только цифры, только буквы) и отбрасывание любых подозрительных символов.
- Использование безопасных API: при работе с URL-фрагментами и параметрами следует использовать методы, которые не интерпретируют данные как код, например,
URLSearchParamsдля чтения параметров строки запроса.
Пример безопасного кода
Вместо: ``javascript var name = window.location.hash.substring(1); document.getElementById('greeting').innerHTML = 'Привет, ' + name + '!'; ` Следует использовать: `javascript var name = window.location.hash.substring(1); document.getElementById('greeting').textContent = 'Привет, ' + name + '!'; ``
Инструменты для обнаружения
Для выявления DOM-based XSS используются как статические, так и динамические методы анализа:
- Статический анализ кода: сканеры исходного кода (например, ESLint с плагинами безопасности, Find Security Bugs) ищут опасные вызовы функций и потенциальные источники недоверенных данных.
- Динамический анализ: браузерные инструменты разработчика (вкладка Sources, Debugger) позволяют отслеживать поток данных и выполнение скриптов. Специализированные инструменты, такие как Burp Suite (с расширением DOM Invader) или OWASP ZAP, могут автоматически тестировать страницы на уязвимости.
- Фаззинг: автоматическая генерация и отправка различных payload в URL-параметры и фрагменты с последующим наблюдением за выполнением JavaScript.
Примеры известных атак
DOM-based XSS неоднократно обнаруживался в популярных веб-приложениях и библиотеках. Например:
- В 2015 году была обнаружена уязвимость в jQuery (
$.htmlPrefilter), которая позволяла выполнять DOM-based XSS в версиях до 1.12.0 и 2.2.0. - В 2018 году исследователи нашли DOM-based XSS в приложении Google+ (закрыто в 2019 году), где вредоносный код мог быть внедрён через параметры URL.
- Уязвимости в библиотеках для работы с шаблонами (например, AngularJS, React) также приводили к DOM-based XSS, если разработчики неправильно использовали методы вставки HTML.
Источники
- OWASP (Open Web Application Security Project). DOM-based XSS Prevention Cheat Sheet.
- OWASP. Types of Cross-Site Scripting.
- PortSwigger Web Security Academy. DOM-based XSS.
- Google Developers. Security: DOM-based XSS.
- Mozilla Developer Network (MDN). Cross-Site Scripting (XSS).
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →