Localhost-атака: как Meta и Яндекс следят за пользователями Android через localhost
- пятница, 6 июня 2025 г. в 00:00:13
Мы раскрыли новый метод отслеживания, используемый компаниями Meta и Яндекс, который потенциально затрагивает миллиарды пользователей Android. Мы обнаружили, что нативные приложения Android — включая Facebook, Instagram и несколько приложений Яндекса, таких как Карты и Браузер — незаметно слушают определенные локальные порты в целях отслеживания.
Эти нативные приложения Android получают метаданные браузеров, куки и команды от скриптов Meta Pixel и Яндекс.Метрики, встроенных на тысячи веб-сайтов. Эти скрипты загружаются в мобильных браузерах пользователей и незаметно связываются с нативными приложениями, работающими на том же устройстве, через локальные сокеты (localhost). Так как нативные приложения программно получают доступ к идентификаторам устройства, таким как рекламный идентификатор Android (AAID), или обрабатывают идентификацию пользователя, как в случае приложений Meta, этот метод позволяет этим организациям связывать сессии мобильного браузера и веб-куки с личностью пользователя, тем самым деанонимизируя посетителей сайтов, на которых размещены их скрипты.
Этот способ передачи идентификаторов из браузера в приложение обходит типичные средства защиты приватности, такие как очистка куки, режим инкогнито и контроль разрешений Android. Более того, он открывает возможность для потенциально вредоносных приложений подслушивать веб-активность пользователей.
Хотя существуют тонкие различия в том, как Meta и Яндекс связывают веб- и мобильные контексты и идентификаторы, по сути обе компании злоупотребляют неконтроллируемым доступом к localhost-сокетам. Операционная система Android позволяет любому установленному приложению с разрешением INTERNET открывать прослушивающий сокет на интерфейсе loopback (127.0.0.1). Браузеры, работающие на том же устройстве, также имеют доступ к этому интерфейсу без согласия пользователя или вмешательства платформы. Это позволяет JavaScript-коду, внедрённому в веб-страницы, взаимодействовать с нативными Android-приложениями и передавать идентификаторы и информацию о действиях пользователя, соединяя эфемерные веб-идентификаторы с долгоживущими идентификаторами мобильных приложений с помощью стандартных веб-API.
Meta (Facebook) Pixel, загруженный в мобильном веб-браузере Android, передаёт first-party cookie _fbp с помощью WebRTC на UDP-порты 12580–12585 любому приложению на устройстве, которое прослушивает эти порты. Мы обнаружили, что принадлежащие Meta Android-приложения Facebook (версия 515.0.0.23.90) и Instagram (версия 382.0.0.43.84), доступные в Google Play Store, прослушивают этот диапазон портов.
С 25 2025 года (в оригинальной статье дата написана именно так - прим. переводчика) Meta Pixel использует технологию, известную как SDP Munging, для вставки содержимого файла cookie _fbp в поле SDP «ice-ufrag», в результате чего сообщение Binding Request STUN отправляется на localhost, как показано на следующем рисунке. Этот поток данных не может быть отслежен с помощью обычных инструментов отладки Chrome (таких как DevTools).
Весь процесс передачи куки _fbp от веб-сайта к нативному приложению и серверу выглядит следующим образом:
Пользователь открывает нативное приложение Facebook или Instagram, которое в конечном итоге отправляется в фоновый режим и создает фоновый сервис для прослушивания входящего трафика на TCP-порту (12387 или 12388) и UDP-порту (первый незанятый порт в диапазоне 12580-12585). Пользователи должны войти в приложения с помощью своих учетных данных.
Пользователь открывает браузер и посещает веб-сайт, на котором интегрирован Meta Pixel.
На этом этапе веб-сайты могут запрашивать согласие в зависимости от местоположения веб-сайта и посетителя.
Скрипт Meta Pixel отправляет cookie _fbp в нативное приложение Instagram или Facebook через WebRTC (STUN) SDP Munging.
Скрипт Meta Pixel также отправляет значение _fbp в запросе на https://www.facebook.com/tr вместе с другими параметрами, такими как URL-адрес страницы (dl), метаданные веб-сайта и браузера, а также тип события (ev) (например, PageView, AddToCart, Donate, Purchase).
Приложения Facebook или Instagram получают файл cookie fbp от JavaScript Meta Pixel, работающего в браузере. Приложения передают fbp в виде GraphQL на (https://graph[.]facebook[.]com/graphql) вместе с другими постоянными идентификаторами пользователей, связывая _fbp ID (посещение веб-сайта) пользователей с их учетной записью Facebook или Instagram.
Примерно 17 мая Meta Pixel добавила в свой скрипт новый метод, который отправляет cookie _fbp с помощью WebRTC TURN вместо STUN. Новый метод TURN позволяет избежать SDP Munging, об отключении которого разработчики Chrome публично объявили после нашего раскрытия информации. По состоянию на 2 июня 2025 года мы не наблюдали, чтобы приложения Facebook или Instagram активно прослушивали эти новые порты.
Согласно Политике Meta в отношении cookie, cookie _fbp идентифицирует браузеры с целью предоставления рекламных услуг и услуг по аналитике сайтов и имеет срок действия 90 дней. Эта cookie присутствует примерно на 25% из миллиона самых популярных веб-сайтов, что делает ее третьей по популярности first-party cookie в Интернете, согласно Web Almanac 2024.
First-party cookie означает, что она не может использоваться для отслеживания пользователей на разных веб-сайтах, поскольку она устанавливается в рамках домена веб-сайта. Это означает, что один и тот же пользователь имеет разные файлы cookie _fbp на разных веб-сайтах. Однако метод, который мы раскрываем, позволяет связывать разные cookie fbp с одним и тем же пользователем, что обходит существующие меры защиты и противоречит интересам пользователей.
Скрипт Яндекс.Метрика инициирует HTTP-запросы с длинными и непрозрачными параметрами к localhost через определенные TCP-порты: 29009, 29010, 30102 и 30103. Наше расследование показало, что приложения, принадлежащие Яндексу, такие как Яндекс.Карты и Яндекс.Навигатор, Яндекс.Поиск и Яндекс.Браузер, активно прослушивают эти порты. Кроме того, наш анализ показывает, что домен yandexmetrica[.]com резолвится в адрес обратной связи 127.0.0.1, а скрипт Яндекс.Метрика передает данные по HTTPS на локальные порты 29010 и 30103. Такой подход затрудняет обнаружение процесса "вывода" данных, что усложняет работу традиционных механизмов обнаружения.
Приложения Яндекса обращаются к домену Yandex (startup[.]mobile[.]yandex[.]net или подобному) для получения списка портов, которые необходимо прослушивать. Эндпоинт возвращает JSON, содержащий локальные порты (например, 30102, 29009) и параметр «first_delay_seconds», который, по нашему мнению, используется для задержки запуска службы. На одном из наших тестовых устройств first_delay_seconds примерно соответствовал количеству секунд, которое потребовалось приложению Яндекса для начала прослушивания локальных портов (~3 дня).
После получения HTTP-запросов localhost от скрипта Яндекс.Метрик мобильное приложение отвечает двоичными данными, закодированными в Base64, в которых содержится Android Advertising ID (AAID) вместе с другими идентификаторами, доступными из Java API, такими как рекламный ID Google и UUID, потенциально специфичные для Яндекса. В отличие от случая с Meta Pixel, вся эта информация агрегируется и загружается на сервер Яндекс.Метрика (например, mc[.]yango[.]com) с помощью кода JavaScript, выполняемого в веб-браузере, а не с помощью нативного приложения. В случае с Яндексом нативное приложение действует как прокси для сбора нативных идентификаторов Android и передачи их в контекст браузера через localhost.
Весь процесс коммуникации Яндекса от веб-приложения к нативному приложению и серверу выглядит следующим образом:
Пользователь открывает одно из нативных приложений Яндекса, которое в конечном итоге отправляется в фоновый режим и создает фоновый сервис для прослушивания входящего трафика на двух HTTP-портах (29009 и 30102) и двух портах (29010 и 30103).
Пользователь открывает браузер и посещает веб-сайт, на котором интегрирован скрипт Яндекс.Метрика.
Скрипт Яндекса отправляет запрос на свои серверы для получения зашифрованных параметров.
Эти зашифрованные параметры отправляются на localhost через HTTP и HTTPS. Это происходит с URL-адресом, который либо напрямую содержит IP-адрес 127.0.0.1, либо домен yandexmetrica[.]com, который разолвится в 127.0.0.1.
SDK Яндекс.Метрики в приложении получает эти параметры и отвечает скрипту Яндекс.Метрики на веб-сайте ответом 200 OK, содержащим зашифрованные идентификаторы устройств.
Скрипт Яндекс.Метрики на веб-сайте получает эти идентификаторы и отправляет их на свои серверы вместе с зашифрованными параметрами.
В этой таблице представлены приложения, принадлежащие Яндексу, которые мы обнаружили на портах localhost. Для каждого приложения мы также указываем его уникальное имя пакета и версию, использованную для тестирования.
Yandex app | Package name | Tested version |
---|---|---|
Yandex Maps |
| 23.5.0 |
Yandex Navigator |
| 23.5.0 |
Yandex Browser |
| 25.4.1.100 |
Yandex Search |
| 25.41 |
Metro in Europe — Vienna |
| 3.7.3 |
Yandex Go: Taxi Food |
| 5.24.1 |
Использование HTTP-запросов для обмена идентификаторами между веб-приложениями и нативными приложениями (т. е. не WebRTC STUN или TURN) может привести к раскрытию истории браузера пользователей третьим лицам. Злонамеренное стороннее приложение для Android, которое также прослушивает вышеупомянутые порты, может перехватить HTTP-запросы, отправленные скриптом Яндекс.Метрики, и первую, теперь неиспользуемую реализацию канала связи Meta, отслеживая HTTP-заголовок Origin.
Мы разработали приложение для демонстрации возможности сбора истории просмотров злонамеренным сторонним приложением. Мы обнаружили, что браузеры Chrome, Firefox и Edge уязвимы для этой формы утечки истории просмотров как в стандартном, так и в приватном (инкогнито) режиме просмотра. Браузер Brave не подвержен этой проблеме благодаря своему списку блокировки и блокировке запросов к localhost; а DuckDuckGo подвержен этой проблеме в минимальной степени из-за отсутствия доменов в его списке блокировки.
Хотя существует вероятность, что другие приложения могут прослушивать эти порты, мы не обнаружили ни одного приложения, не принадлежащего Meta или Яндексу, которое бы прослушивало эти порты.
Ссылка на видеодемонстрацию: https://localmess.github.io/assets/video/Yandex_Browsers_compressed.mp4
Поскольку Яндекс использует HTTP-запросы для связи с локальным хостом, любое приложение, прослушивающее необходимые порты, может отслеживать веб-сайты, которые посещает пользователь, с помощью функций отслеживания, как показано в видео выше. Сначала мы открываем наше приложение для проверки концепции, которое прослушивает порты, используемые Яндексом, и отправляем его в фоновый режим. Затем мы посещаем пять веб-сайтов в разных браузерах. После этого мы видим URL-адреса этих пяти сайтов, перечисленные в приложении
Согласно BuiltWith, веб-сайту, который отслеживает внедрение веб-технологий: Meta Pixel встроен в более чем 5,8 миллиона веб-сайтов. Яндекс.Метрика, с другой стороны, присутствует на почти 3 миллионах веб-сайтов. Согласно HTTP Archive, открытому и общедоступному набору данных, который ежемесячно сканирует около 16 миллионов веб-сайтов, Meta Pixel и Яндекс.Метрика присутствуют на 2,4 миллиона и 575 448 веб-сайтах соответственно.
Сканирование 100 000 самых популярных домашних страниц: мы провели два сканирования 100 000 самых популярных сайтов (по рейтингу CrUX) с серверов, расположенных во Франкфурте и Нью-Йорке, чтобы оценить, насколько широко используются сокеты localhost на сайтах. В следующей таблице показано количество сайтов, на которых было обнаружено данное явление. В первой колонке для каждого региона указано количество сайтов, встраивающих эти трекеры при принятии всех форм согласия на использование файлов cookie. Во второй колонке (с пометкой «без согласия») указано количество сайтов, которые по умолчанию активно пытаются установить связь с localhost, как только пользователь загружает их в браузере, т. е. потенциально без согласия пользователя.
Script name | US presence | US no consent | Europe presence | Europe no consent |
---|---|---|---|---|
Meta Pixel | 17,223 | 13,468 (78.2%) | 15,677 | 11,890 (75.8%) |
Yandex Metrica | 1,312 | 1,095 (83.5%) | 1,260 | 1,064 (84.4%) |
В следующей таблице показана эволюция методов, используемых Яндексом и Meta, с указанием даты, когда каждый метод был впервые замечен на основе исторических данных HTTP Archive.
Method | Start date (first seen) | End date (last seen) | Ports | Har files | |
---|---|---|---|---|---|
Yandex | HTTP | Feb 2017 | - | 29009, 30102 | |
HTTPS | May 2018 | - | 29010, 30103 | - | |
Meta | HTTP | Sep 2024 | Oct 2024* | 12387 | |
Websocket | Nov 2024 | Jan 2025 | 12387 | ||
WebRTC STUN (w/ SDP Munging) | Nov 2024 | - | 12580-12585 | ||
WebRTC TURN** (w/o SPD Munging) | May 2025 | - | 12586-12591 | - |
Этот новый метод отслеживания использует неограниченный доступ к сокетам localhost на платформах Android, включая большинство браузеров Android. Как мы показываем, эти трекеры выполняют эту практику без ведома пользователей, поскольку текущие средства контроля конфиденциальности (например, подходы с использованием песочниц, разрешения мобильных платформ и браузеров, модели согласия в Интернете, режимы инкогнито, сброс мобильных рекламных идентификаторов или очистка файлов cookie) недостаточны для контроля и смягчения этой проблемы.
Наше ответственное раскрытие информации основным вендорам браузеров для Android привело к появлению нескольких патчей, направленных на устранение этой проблемы; некоторые из них уже внедрены, другие находятся в стадии разработки. Мы благодарим всех участвующих вендоров (Chrome, Mozilla, DuckDuckGo и Brave) за их активное сотрудничество и конструктивное участие на протяжении всего процесса. Другие браузеры на базе Chromium должны следовать изменениям в апстриме, чтобы исправить свои собственные продукты.
Однако, помимо этих краткосрочных исправлений, для полного решения проблемы потребуется более широкий набор мер, поскольку они не охватывают фундаментальные ограничения методов и политик песочницы платформ. К ним относятся средства контроля, ориентированные на пользователей, для оповещения их о доступе к localhost, более строгие политики платформ, сопровождаемые последовательными и строгими мерами по предотвращению злоупотреблений, а также усиление безопасности механизмов межпроцессного взаимодействия (IPC) Android, особенно тех, которые полагаются на соединения localhost.
Browser | Version | Yandex | Mitigations | |
---|---|---|---|---|
Chrome | 136.0.7103.125 | Affected | Affected | Версия 137, выпущенная 26 мая 2025 года, содержала меры противодействия для блокировки злоупотребляемых портов и отключения конкретной формы SDP-мунгинга, которую использовал Meta Pixel. По состоянию на 2 июня 2025 года эти меры защиты проходят испытания для части пользователей Chrome и, вероятно, скоро будут доступны для широкой публики. Наши тесты показали, что эти меры защиты блокируют используемые в настоящее время формы локального обмена данными Meta и Яндекс. В долгосрочной перспективе предлагаемый стандарт доступа к локальной сети может стать более принципиальным решением для ограничения такого рода злоупотреблений. |
Microsoft Edge | 136.0.3240.50 | Affected | Affected | (неизвестно) |
Firefox | 138.0.2 | Affected | Not affected.1 | В процессе. |
DuckDuckGo | 5.233.0 | Minimally affected2, 3 | Not affected3 | Дополнен черный список |
Brave | 1.78.102 | Not affected3 | Not affected3, 4 | Не затронуто. С 2022 года для связи с localhost требуется согласие пользователя, а также реализован черный список адресов. |
SDP-обработка учетных данных ICE заблокирована, однако UDP-соединения с портами TURN пока не заблокированы (они будут заблокированы в версии 138). Мета-приложения, которые мы тестировали, на момент выпуска не прослушивают порты TURN, но скрипты Meta Pixel уже отправляют данные на порты TURN.
Три альтернативных домена Yandex отсутствовали в списке блокировки DuckDuckGo, но эти домены появлялись на очень небольшом количестве веб-сайтов (31/100K). DuckDuckGo быстро исправил свой список блокировки, чтобы устранить эту уязвимость.
Защита на основе списка блокировки.
Блокирует запросы к «127.0.0.1» и «localhost».
Мы не нашли никакой публичной документации от Meta или официальной документации Яндекса, описывающей этот метод и его цель. В отношении Meta Pixel мы нашли несколько жалоб от озадаченных владельцев веб-сайтов, которые задавали вопрос, почему Meta Pixel связывается с localhost, на форумах разработчиков Facebook в сентябре 2024 года:
Эти жалобы поступают со всего мира. В этих ветках нет официального ответа от представителей Meta. Один разработчик заявил в сентябре 2024 года: "Однако от Meta не поступило никакого подтверждения по этому поводу. Мой запрос в службу поддержки получил общий ответ, а затем был проигнорирован." "Жаль, что ответственность не была взята на себя, мы полагаемся на то, что эти инструменты работают правильно, и не имеем над ними контроля, поэтому, как минимум, нам должны дать объяснение, что пошло не так."
Вполне вероятно, что пользователи, просматривающие Интернет и посещающие сайты, интегрирующие Яндекс и Meta ID, связывающие веб-приложения и нативные приложения, могут не быть полностью осведомлены об этом поведении. Фактически, новый метод отслеживания работает даже в том случае, если пользователь:
не залогинен в Facebook, Instagram или Яндексе в своем мобильном браузере
использует режим инкогнито
очищает свои куки или другие данные браузера
Этот метод отслеживания обходит межпроцессную изоляцию Android и средства защиты от отслеживания, основанные на разделении, песочнице или очистке состояния на стороне клиента.
Предварительные результаты показывают, что эти методы могут быть реализованы на веб-сайтах без явных и надлежащих форм согласия на использование файлов cookie. Если сайт загружает скрипты Facebook или Яндекса до того, как пользователь дал согласие на использование соответствующих файлов cookie, это поведение все равно будет запущено.
В: Почему Facebook перестал использовать эту технику в день вашего публичного заявления?
О: Мы не знаем ¯\_(ツ)_/¯, но рады видеть, что после нашего заявления (по крайней мере, на данный момент) пользователи Android больше не подвергаются этому типу злоупотребления.
В: Прошло ли это исследование экспертную оценку?
О: Наши выводы были подтверждены некоторыми сторонами, которым мы их раскрыли, но исследование еще не прошло экспертную оценку. Мы решили не откладывать публичное раскрытие информации из-за серьезности активного злоупотребления.
В: Раскрыли ли Meta или Яндекс этот метод в своей документации?
О: Мы не нашли публичной технической документации от Meta или Яндекса, описывающей эту конкретную технику связи на основе localhost. На форумах разработчиков Facebook некоторые высказывали опасения по поводу скриптов Pixel, связывающихся с localhost, но не получили никаких объяснений.
В: Это касается только пользователей Android? А как насчет iOS или других платформ?
О: Мы получили только эмпирические доказательства того, что веб-скрипты Meta и Яндекса, которые соединяют веб-адреса с нативными идентификаторами, были нацелены исключительно на мобильных пользователей Android. В браузерах и приложениях iOS, которые мы тестировали, не было обнаружено никаких доказательств злоупотребления. Тем не менее, аналогичный обмен данными между браузерами iOS и нативными приложениями технически возможен. Браузеры iOS, которые все основаны на WebKit, позволяют разработчикам программно устанавливать соединения с localhost, а приложения могут прослушивать локальные порты. Возможно, технические и политические ограничения на запуск нативных приложений в фоновом режиме объясняют, почему пользователи iOS не были целью этих трекеров. Однако мы отмечаем, что наш анализ iOS все еще является предварительным, и такое поведение могло также нарушать политику PlayStore. Помимо мобильных платформ, соединение веб-идентификаторов с нативными идентификаторами может также представлять угрозу для настольных ОС и платформ смарт-телевизоров, но мы еще не исследовали эти платформы.
ОБНОВЛЕНИЕ: По состоянию на 3 июня, 7:45 CEST, скрипт Meta/Facebook Pixel больше не отправляет пакеты или запросы на localhost. Код, отвечающий за отправку файла cookie _fbp, был почти полностью удален.
P.S. Эта статья - перевод. Оригинал здесь: https://localmess.github.io/
Авторы исследования:
Aniketh Girish (PhD student) | IMDEA Networks | |
Gunes Acar (Assistant Professor) | Radboud University, Digital Security Group & iHub | |
Narseo Vallina-Rodriguez (Associate Professor) | IMDEA Networks | |
Nipuna Weerasekara (PhD student) | IMDEA Networks | |
Tim Vlummens (PhD student) | COSIC, KU Leuven |