Исторический сниффинг
Исторический сниффинг (англ. history sniffing) — это класс веб-уязвимостей и атак, которые позволяют веб-сайту отслеживать действия пользователя в истории веб-браузера, фиксируя, какие сайты пользователь посещал, а какие — нет. Это достигается за счёт использования давних проблем утечки информации, присущих архитектуре веб-платформы, самой известной из которых является детектирование изменений CSS-атрибутов у ссылок, уже посещённых пользователем.
Обобщённая классификация векторов атак включает следующие категории:
- Утечки через CSS: метод основан на проверке стилей (например, селектора
a:visited) для определения, отображается ли ссылка как посещённая. В современных браузерах эта уязвимость в основном устранена, так как API возвращают данные так, будто все ссылки являются непосещёнными[1].[2] - Утечки через тайминги и кэш: метод основан на измерении времени загрузки ресурсов. Если ресурс загружается из кэша браузера или DNS-кэша, это происходит значительно быстрее, что позволяет сделать вывод о недавнем посещении сайта[1].[2]
- Утечки через новые функции и API браузеров: появление новых динамичных и интерактивных функций открывает возможности для эксплойтов (например, использование AppCache, получение ошибок через JavaScript-событие
onerrorи оценка размера ресурсов)[1].[2]
Несмотря на то, что проблема известна с 2002 года, исторический сниффинг до сих пор считается нерешённой задачей. В 2010 году исследователи сообщили, что несколько известных веб-сайтов использовали такие методы для идентификации и отслеживания пользователей. Вскоре после этого Mozilla и другие крупные производители браузеров внедрили механизмы защиты от исторического сниффинга. Тем не менее современные исследования показывают, что эти меры неэффективны против некоторых вариантов атак, и исторический сниффинг остаётся возможным как через посещённые ссылки, так и с помощью новых функций браузеров.
Предпосылки
Ранние веб-браузеры, такие как Mosaic и Netscape Navigator, были построены на представлении о вебе как о совокупности статически связанных между собой документов, известных как страницы. В такой модели было логично показывать пользователю, какие документы он уже посещал, а какие — нет, независимо от того, из какого документа осуществляется переход[3]. Mosaic, один из первых графических браузеров, использовал фиолетовые ссылки для обозначения посещённых страниц, а синие ссылки — для тех, что не были посещены[4][5]. Эта парадигма прижилась и позднее была перенята всеми современными браузерами[6].
Со временем веб эволюционировал от модели статического контента к более динамической. В 1995 году сотрудники компании Netscape добавили скриптовый язык Джаваскрипт в свой флагманский браузер Netscape Navigator, что позволило внедрять интерактивность посредством исполнения программ на Джаваскрипте во время рендеринга[7][8]. Однако появление скриптов породило новые проблемы безопасности — программы на Джаваскрипте могли получить доступ к контексту выполнения друг друга и к конфиденциальной информации пользователя. В результате вскоре в Netscape Navigator была введена политика одного источника, ограничивающая доступ скриптов к данным из других веб-страниц. Хотя политика одного источника со временем была распространена на множество других функций браузера, ссылки никогда не подпадали под её действие, чтобы не ухудшать удобство навигации для пользователя[6]. Это на первый взгляд безобидное упущение стало одной из самых ранних и известных уязвимостей исторического сниффинга в вебе[9].
Наряду с уязвимостями CSS-ссылок, другим ранним вектором атак (в период с 1995 по 2010 год) была эксплуатация механизмов кэширования браузера. Исторический сниффинг в этом случае осуществлялся путём измерения времени загрузки веб-ресурсов с помощью JavaScript: скрипт инициировал загрузку определённого файла с целевого сайта и фиксировал скорость его получения. Если файл загружался очень быстро, это означало, что он был извлечён из локального кэша, а не скачан заново по сети. Опираясь на разницу во времени между загрузкой кэшированных и новых объектов, веб-сайты могли с высокой долей вероятности определять, посещал ли пользователь проверяемый ресурс недавно[10].
История
Одно из первых публичных сообщений об эксплойте исторического сниффинга оставил Эндрю Кловер из Пёрдьюского университета в рассылке BUGTRAQ в 2002 году, описав, как вредоносный сайт может определить с помощью Джаваскрипта, был ли определённый линк определённого цвета, тем самым узнавая, посещал ли пользователь эту страницу[11]. Хотя поначалу уязвимость считалась сугубо теоретической, в 2010 году Jang и др. показали, что ряд известных сайтов действительно эксплуатирует этот подход для сбора данных о действиях пользователей[12]. В результате против сайтов, уличённых в историческом сниффинге, были поданы судебные иски по обвинению в нарушении Закона о компьютерном мошенничестве и злоупотреблениях 1986 года[9].
В том же году Л. Дэвид Барон из Mozilla Corporation разработал защиту против таких атак, которую в дальнейшем переняли все ведущие браузеры: были введены ограничения на использование свойств CSS для стилизации посещённых ссылок, запрет на фоновые изображения и CSS-переходы, а обращения к программным интерфейсам приложения через Джаваскрипт стали возвращать одинаковые значения свойств для посещённых и непосещённых ссылок. Таким образом, сайты не могли узнавать историю посещений по изменению цвета элементов[13].
В 2011 году исследование аспиранта Стенфордского университета Джонатана Майера показало, что рекламная компания Epic Marketplace Inc. использовала исторический сниффинг для сбора информации о посещаемых пользователем веб-сайтах[14]. Впоследствии расследование Федеральной торговой комиссии США (FTC) выявило, что Epic Marketplace внедряла код исторического сниффинга в рекламу на более чем 24 000 доменов, включая ESPN и Papa Johns. Джаваскрипт-код позволял проверять, посещал ли пользователь любой из более чем 54 000 доменов[15][16]. Собранные данные использовались для категоризации пользователей и отображения рекламы на основе их истории посещений. В результате расследования FTC запретила Epic Marketplace Inc. заниматься онлайн-рекламой и маркетингом на 20 лет, а также обязала удалить ранее собранные данные[17][16].
Модель угроз
Модель угроз исторического сниффинга основывается на возможности злоумышленника полностью или частично контролировать веб-страницу, на которую перенаправляется пользователь. Для этого злоумышленник может скомпрометировать ранее безопасный сайт, заманить жертву фишинговой рассылкой на специально подготовленную страницу или встроить вредоносную рекламу на обычный сайт[9][18]. Хотя большинство атак не требует активных действий пользователя, некоторые их разновидности полагаются на взаимодействие с элементами, замаскированными под кнопки, браузерные игры, капчи и пр[6].
Исторический сниффинг применяется на начальном этапе многоступенчатых атак для сбора данных о жертве. Знание того, какими сервисами или банками пользуется пользователь, позволяет злоумышленникам персонализировать угрозу (осуществлять «умный фишинг») и перенаправлять жертву на релевантные поддельные страницы для кражи учётных или финансовых данных[19]..
Современные исследования и статус проблемы
Несмотря на частичную блокировку в 2010 году, исторический сниффинг остаётся нерешённой проблемой[9]. В 2011 году исследователи из Университета Карнеги — Меллона показали, что защиты Mozilla эффективны против большинства неинтерактивных атак, однако бессильны против атак с участием пользователя. Демонстрируя буквы, числа и паттерны, которые становились видимыми только при посещённых определённых сайтах, исследователи смогли убедить 307 участников потенциально раскрыть свои истории посещений через выполнение заданий по распознаванию паттернов, шахматным играм и капчам[20][6].
В 2018 году исследователи из Калифорнийского университета в Сан-Диего и Стэнфорда представили четыре новых метода обхода защитных мер браузеров с помощью тайминговых атак: CSS Paint API, CSS 3D transforms, SVG-заливка и кэш байт-кода JavaScript[21].
С 2019 года появились новые атаки исторического сниффинга, использующие современные возможности браузеров. В 2020 году Sanchez-Rola и др. показали, что, измеряя время ответа сервера на запрос с HTTP-cookie и без них, можно так же выявлять посещённые объекты[22]. Исследование 2023 года показало, что большинство современных браузеров остаются уязвимыми к атакам из-за внедрения новых функций, обходящих старые ограничения; единственным устойчивым браузером оказался Tor. В том же году Али и др. продемонстрировали, что новые механизмы браузера, такие как Private Tokens API в рамках инициативы Privacy Sandbox, могут позволить злоумышленникам получать историю посещений[23]. Позднее в экосистеме Privacy Sandbox было обнаружено 12 новых векторов атак, включая кросс-сайтовые утечки через механизм FLEDGE[24]. Для фундаментального решения проблемы к 2026 году в Chromium внедряется механизм партиционирования состояния (State Partitioning)[25].
Векторы атак по сторонним каналам
Эволюция механизмов утечки
В период с 2013 по 2023 год в ходе эволюции уязвимостей, связанных с историческим сниффингом, произошёл переход от прямого доступа к данным к использованию сложных побочных каналов. Среди основных механизмов утечки через архитектуру браузера выделяются:
- Нагрузка на кэш процессора (CPU cache contention) — при изменении статуса посещённой ссылки браузер пересчитывает стили, вызывая высокую нагрузку на кэш последнего уровня.
- Аппаратное ускорение (GPU contention) — пересчёт сложных стилей занимает графический процессор, что позволяет фиксировать замедление ответов на простые задачи (например, при использовании WebGL).
- Тайминги отрисовки (Rendering performance) — применение тяжёлых CSS-стилей к ссылкам снижает эффективную частоту кадров браузера, что можно измерить через подсчёт вызовов
requestAnimationFrame. - Тайминги отрисовки через CSS Paint API — скрытое измерение времени перерисовки изображения, связанного с целевым URL (метод эффективен в Chrome с 2017 года)[26].
Атаки на кэш и тайминги DNS
Основным методом атак по сторонним каналам на локальный или удалённый кэш DNS является техника Evict+Reload. Злоумышленник принудительно очищает DNS-кэш жертвы, после чего измеряет задержки при разрешении доменных имён. Небольшое время отклика означает, что домен был закэширован повторно, что свидетельствует о недавнем посещении соответствующего сайта пользователем. Современные механизмы защиты не предотвращают подобные уязвимости, а использование протокола DNSSEC повышает точность атаки[27].
В сети Tor применяется атака типа «timeless timing attack» на DNS-кэш выходных узлов. Она позволяет безошибочно определить наличие домена в кэше, полностью исключая влияние сетевых задержек. Данный метод демонстрирует абсолютную надёжность и является эффективным побочным каналом для подтверждения посещения сайтов и деанонимизации пользователей[28].
Уязвимости Service Workers
Вектор атаки через перехват запросов с использованием Performance API основан на размещении iframe на стороннем сайте для загрузки ресурсов целевого домена, что активирует его Service Worker. С помощью интерфейса PerformanceResourceTiming проверяются атрибуты workerStart и nextHopProtocol. Если запрос перехватывается Service Worker, workerStart возвращает ненулевое значение, а nextHopProtocol — пустую строку, что позволяет определить факт предыдущего посещения сайта пользователем. В браузерах на базе Chromium данная уязвимость была исправлена: для кросс-доменных iframe атрибут workerStart принудительно возвращает 0. В Firefox эти атрибуты также были ограничены, однако это привело к появлению новой утечки, при которой атрибут duration стал возвращать 0 при перехвате запроса.
Другой вектор атаки связан с анализом состояния кэша через тайминги. Атакующий измеряет время загрузки ресурса через iframe, одновременно запрашивая обычный URL и URL с уникальным параметром, заставляющим браузер загружать файл напрямую из сети. Если обычный ресурс загружается значительно быстрее за счёт извлечения из кэша Service Worker, это подтверждает наличие установленного обработчика и факт посещения целевого сайта. Полноценная защита от таких атак на уровне браузеров требует сложной переработки механизмов изоляции сайтов. В качестве доступной меры противодействия разработчикам предлагается внедрять проверку заголовка referrer внутри самого Service Worker: если запрос поступает от неавторизованного стороннего домена, он должен направляться напрямую в сеть в обход кэша.
Эксплуатация HSTS-кэша
Метод сниффинга через HSTS основан на проверке статуса HSTS путём загрузки подресурсов по HTTP. Сторонний скрипт пытается загрузить ресурсы (например, изображения) с проверяемых доменов по HTTP. Если домен сохранён в HSTS-кэше браузера после его посещения, запрос автоматически выполняется по HTTPS. Отслеживая, какие запросы идут по HTTP, а какие по HTTPS, злоумышленник может определить наличие домена в кэше, что раскрывает историю посещений или позволяет прочитать сохранённый уникальный идентификатор пользователя для трекинга. В современных браузерах для предотвращения сниффинга истории и трекинга применяется ограничение: автоматические HSTS-апгрейды действуют только для навигации верхнего уровня (top-level navigations). Это делает невозможным скрытое чтение HSTS-кэша через фоновую загрузку подресурсов[29]..