Содержание статьи
Что такое DOM?
DOM (Document Object Model) — не зависящий от платформы и языка программный интерфейс, который позволяет программам и скриптам получать доступ к содержимому HTML-, XHTML-, XML-документов, а также изменять их контент (содержимое, структуру, оформление). DOM-based-уязвимости возникают, когда веб‑сайт содержит сценарий, который принимает контролируемое злоумышленником значение и передает его небезопасной функции, называемой sink. Один из видов DOM-based-уязвимостей — DOM-based XSS. Уязвимости этого типа возникают, когда JavaScript получает данные от пользователя и передает их в sink, обладающий возможностью динамического исполнения кода, например eval(
, document.
или innerHTML
.
Как эксплуатируются DOM-based XSS?
Наиболее популярный источник DOM XSS — URL-страницы. Доступ к этому значению осуществляется с помощью JavaScript через объект window.
. Затем URL обрабатывается внутри существующего на странице легитимного скрипта. В этом случае атакующий может создать ссылку с вредоносной нагрузкой, чтобы затем отправить ее жертве. Когда жертва перейдет по ссылке, исходный скрипт на странице, использующий объект window.
, запросит адрес текущей страницы и исполнит нагрузку, которая содержится в URL. Вот простейший пример этой уязвимости.
<body><script>document.write(location.href);</script></body>
При получении такой страницы браузер автоматически выполнит скрипт и запишет в тело страницы (document.
) строку, взяв ее значение из location.
(полного адреса страницы). Однако пользователь контролирует значение location.
и может поместить в него произвольную строку. Поэтому для эксплуатации XSS-уязвимости достаточно сформировать следующую ссылку, и при ее открытии в браузере выполнится вредоносный скрипт.
http://website.com/index.html#<script>alert(1)</script>
Механизмы безопасности кросс-доменного взаимодействия
Представим, что у нас есть страница сайта, который мы разработали. Мы помещаем на нее элемент <
и указываем в качестве его источника произвольный сайт.
Если бы не было механизмов безопасности, обмен данными между элементами родительской веб‑страницы и веб‑страницы, которая отображается в <
, мог бы быть критически опасным для пользовательских данных. Любой скрипт, находящийся на родительской странице, мог бы получить доступ к любым данным, размещенным внутри <
.
Давай рассмотрим на примере. Злоумышленник помещает на своей странице <
с адресом интернет‑банка, в котором пользователь был авторизован ранее. Затем каким‑то образом заманивает жертву на свою страницу. В результате злоумышленник может получить доступ к любым пользовательским данным личного кабинета интернет‑банка жертвы. Чтобы не допустить подобного, были созданы два механизма защиты:
-
Same Origin Policy (SOP), «политика одинакового источника», — предотвращает кросс‑доменные атаки, блокируя чтение загружаемых ресурсов из другого источника. Источник идентифицируется по следующей тройке параметров: схема, полное имя хоста и порт. Когда хотя бы один из параметров у источников не совпадает, обмен данными между ресурсами запрещается. Например, если страница по адресу
http://
попробует отобразить данные из источникаexample. com/ index. html https://
, то это действие будет запрещено, так как у источников не совпадает протокол.example. com/ Cross-Origin Resource Sharing. Ограничения политики одинаковых источников оказались слишком жесткими. Поэтому для более тонкой настройки доступа к ресурсам создали «механизм совместного использования ресурсов разными источниками» — CORS. Он регламентирует три категории сетевого взаимодействия:
- запись из разных источников. Эта категория регламентирует переадресации, отправки форм и переходы по ссылкам. По умолчанию все эти действия разрешены;
- вставка из разных источников. Эта категория регламентирует элементы, загружаемые посредством тегов
<
,link> <
,script> <
,img> <
,video> <
,audio> <
и других. По умолчанию все они разрешены, однако работоспособность тегаiframe> <
может быть дополнительно ограничена с помощью заголовкаiframe> X-Frame-Options
; - считывание из разных источников. Эта категория регламентирует элементы, загружаемые через AJAX и fetch. По умолчанию эти возможности заблокированы.
www
Подробнее о CORS и SOP ты можешь прочитать, к примеру, в этих статьях на «Хабрахабре»: «CORS для чайников: история возникновения, как устроен и оптимальные методы работы» и «Политика общего происхождения и CORS: визуальное руководство».
Web Messaging API
Window.
— это метод, позволяющий передавать данные между документами, которые загружены в разных окнах или фреймах, в том числе между документами, полученными с разных доменов. Если на сайте корректно настроены механизмы безопасности (SOP и CORS), использование postMessage
будет единственным доступным способом передачи данных между документами на разных доменах. Запросы, созданные с помощью прочих методов (как, например, XMLHttpRequest
или Fetch API), будут заблокированы в соответствии с SOP и CORS.
Поиск информации о технологии postMessages привел меня к официальной документации Mozilla. Обычно сценариям из разных источников разрешен доступ друг к другу тогда и только тогда, когда они соответствуют Same Origin Policy (одинаковая схема, имя хоста и порт), включая сценарии внутри фрейма, которые обращаются к родителю фрейма. Window.
предоставляет контролируемый механизм для безопасного обхода этого ограничения. Также я нашел в документации способы обеспечения связи между родительской страницей и страницей внутри фрейма. В общем виде дочерний <
должен быть подписан на событие «сообщение»:
window.addEventListener("message", (event) => {...}, false);
Здесь message
— ожидаемое сообщение.
В таком случае родительская страница может передать дочернему фрейму сообщение с помощью такого метода:
postMessage(message, targetOrigin, transfer)
Здесь message
— отправляемое сообщение, эти данные автоматически сериализуются для передачи в дочерний фрейм, а targetOrigin
указывает источник родительского окна.
В качестве targetOrigin
допускается использовать звездочку, которая указывает на то, что получить сообщение может кто угодно. Либо можно указать конкретный URI, который будет проверен внутри слушателя в дочернем фрейме. Если Origin страницы не совпадает с targetOrigin
внутри этой функции, событие не будет отправлено. Этот механизм обеспечивает контроль над тем, куда отправляются сообщения. Например, если postMessage
используется для отправки пароля, необходимо, чтобы этот аргумент соответствовал целевому URI. Это позволит предотвратить хищение пароля злоумышленником через недоверенный ресурс.
DOM-based XSS через Web Messaging
Давай посмотрим, как можно использовать веб‑сообщения в качестве источника для создания и эксплуатации DOM XSS на целевой странице. Если целевая страница обрабатывает входящие сообщения небезопасным образом (например, неверно проверяя источник входящих сообщений), то вызываемые слушателем события потенциально могут стать приемниками небезопасной нагрузки и источником XSS.
Например, злоумышленник может поместить на своей странице вредоносный <
и использовать метод postMessage(
для передачи данных с помощью веб‑сообщения уязвимому слушателю событий. В дальнейшем слушатель передаст вредоносную нагрузку в приемник на дочерней странице.
Это значит, что веб‑сообщения могут быть использованы в качестве источника нагрузки для любого из приемников дочерней веб‑страницы. Результат эксплуатации уязвимости зависит от того, как целевой документ обрабатывает полученные сообщения.
Если целевая страница полностью доверяет отправителю, не проверяет данные, полученные от него, и без искажений передает их в приемник, то эта уязвимость позволит злоумышленнику совершить любые действия от лица пользователя в контексте целевого ресурса (скомпрометировать пользователя).
Давай рассмотрим разные варианты уязвимого кода.
Origin Verification отсутствует
Продолжение доступно только участникам
Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
Вариант 2. Открой один материал
Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.
Я уже участник «Xakep.ru»