Открыть сервис

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, что приводит к выполнению скрипта в контексте безопасности текущего сайта.

Типичный сценарий атаки

  1. Пользователь переходит по специально сформированной ссылке, содержащей вредоносный код в параметре URL (например, http://example.com/page.html#<script>...</script>`).
  2. Браузер загружает легитимную страницу page.html с сервера.
  3. JavaScript-код на странице считывает значение из window.location.hash (или другого клиентского источника) и вставляет его в DOM с помощью методов, таких как innerHTML, document.write, document.createElement с последующим добавлением атрибутов, или через jQuery-функции типа .html().
  4. Браузер интерпретирует вставленный код как 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-кода, который работает с данными из клиентских источников.

Основные принципы

  1. Экранирование (escaping): все данные, полученные из ненадёжных источников, должны быть экранированы перед вставкой в DOM. Для вставки текста следует использовать textContent вместо innerHTML, а для вставки HTML — строгую санитизацию с помощью специализированных библиотек, таких как DOMPurify.
  2. Избегание опасных методов: не использовать eval, innerHTML, document.write и другие функции, интерпретирующие строки как код, если данные могут быть контролируемы пользователем.
  3. Использование Content Security Policy (CSP): политика безопасности контента может ограничить выполнение встроенных скриптов и предотвратить атаки, даже если вредоносный код будет вставлен в DOM. Однако CSP не является полной защитой от DOM-based XSS, так как атака может использовать разрешённые источники скриптов.
  4. Валидация на стороне клиента: проверка входных данных на соответствие ожидаемому формату (например, только цифры, только буквы) и отбрасывание любых подозрительных символов.
  5. Использование безопасных 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 →