Браузеры на базе WebKit в iOS и macOS можно настроить так, чтобы весь веб-трафик направлялся через прокси-серверы. Именно так работают все прокси-браузеры на iOS, включая Tor-браузеры и собственный браузер команды Mysk — Psylo. Каждое сетевое соединение, которое создаёт веб-страница, должно проходить через настроенный прокси, поэтому сайты видят только IP-адрес прокси. Исследователи Mysk обнаружили три функции WebKit, которые обходят настройки прокси и отправляют трафик напрямую с устройства:
- DNS prefetching резолвит имена хостов через обычный DNS-путь устройства, раскрывая реальные DNS-серверы пользователя вместо серверов прокси. Доступно с iOS 26.0.
- WebAuthn Related Origin Requests заставляет системный сервис учётных данных получать файл проверки напрямую с устройства. Это раскрывает реальный IP-адрес устройства. Доступно с iOS 18.0.
- WebTransport открывает прямое HTTP/3-соединение в обход прокси, также раскрывая реальный IP-адрес устройства. Доступно с iOS 26.4.
Эти утечки также затрагивают iCloud Private Relay от Apple. Стоит отметить, что VPN эта проблема не касается, поскольку они туннелируют весь сетевой трафик устройства на системном уровне.
Команда Mysk связалась с Tor Project и разработчиками Onion Browser для iOS по поводу этих проблем.
Проверить утечки можно на демонстрационном сайте leaks.psylo.app.
Исправлено в Psylo 1.3.1: Psylo теперь блокирует подсказки
dns-prefetchи по умолчанию отключает WebTransport и WebAuthn. Для сайтов, которым эти функции действительно нужны, каждую можно включить обратно через переключатели для отдельного «силоса». Такое явное согласие оставляет компромиссы приватности в руках пользователя.
Предыстория
Настройка прокси на iOS и macOS
Введённый в iOS 17 и macOS 14 API WKWebsiteDataStore.proxyConfigurations позволяет браузерам на базе WebKit направлять весь собственный веб-трафик через прокси-серверы на уровне приложения. Этот API лежит в основе всех прокси-браузеров на iOS: каждое сетевое соединение, создаваемое веб-страницей, должно проходить через настроенный прокси, поэтому сайты видят только IP-адрес прокси.
DNS-утечка, о которой сообщил пользователь Psylo
Расследование началось с сообщения об ошибке от пользователя Psylo, заметившего DNS-утечки только при посещении некоторых сайтов. Psylo направляет весь трафик из каждого «силоса» через частную прокси-сеть Mysk (или через собственный настроенный пользователем прокси), поэтому DNS-запросы должны исходить исключительно от прокси-сервера, а не от устройства. Странным также казалось, что проблема возникала лишь на некоторых сайтах, а не на всех.
При более глубоком изучении был найден источник DNS-утечек, а также ещё две утечки, раскрывающие реальный IP-адрес устройства. Все три утечки находятся в WebKit, где они обходят настройки прокси, заданные через WKWebsiteDataStore.proxyConfigurations. Поскольку политика App Store требует от каждого iOS-браузера использовать WebKit, проблема затрагивает любой iOS-браузер, полагающийся на этот API для проксирования, включая все Tor-браузеры для iOS и Psylo. Эти утечки также присутствуют в iCloud Private Relay от Apple. VPN, в свою очередь, эти проблемы не затрагивают, поскольку весь сетевой трафик устройства туннелируется через VPN на системном уровне.
iCloud Private Relay
iCloud Private Relay — функция приватности Apple для подписчиков iCloud+. При включении она проксирует веб-трафик и DNS-запросы только Safari через двухступенчатое реле, спроектированное так, чтобы ни одна сторона, даже сама Apple, не могла одновременно видеть, кто пользователь и какие сайты он посещает. Как оказалось, все три описанные в статье утечки происходят вне стандартного процесса загрузки страниц WebKit, а значит Private Relay подвержена тем же утечкам.
1. DNS Prefetching
DNS prefetching позволяет сайту попросить браузер заранее разрешить имя хоста до того, как оно понадобится. Когда позже происходит подключение к этому хосту, поиск уже выполнен, и соединение устанавливается быстрее. Реализуется это через HTML-тег <link rel="dns-prefetch">.
Когда страница содержит такой тег, WebKit разрешает имя хоста через обычный DNS-путь устройства, независимо от прокси, заданного браузером через WKWebsiteDataStore.proxyConfigurations. Страница может внедрить в такие теги уникальные для каждого посетителя имена хостов, а затем наблюдать, как запросы приходят на её собственный авторитетный DNS-сервер из реальной сети посетителя, а не из сети прокси.
Именно эта утечка стояла за первоначальным сообщением пользователя, и она объясняет, почему проблема возникала лишь на некоторых сайтах: без тегов prefetch на странице WebKit не выполняет этот DNS-поиск.
Private Relay эту утечку не перехватывает. Обычно она проксирует DNS-запросы Safari, но запросы prefetch её обходят. Запрос доходит до авторитетного сервера из реальной сети устройства даже при включённой Private Relay.
Desktop Safari поддерживает
<link rel="dns-prefetch">начиная с Safari 5, но iOS игнорировала этот тег вплоть до iOS 26.0 (сентябрь 2025), когда WebKit включил его в том же изменении, которое убрало более старый неявный спекулятивный DNS prefetching в iOS (bug 285744, 290327@main; данные совместимости браузеров). Тот резолвер был переписан годом ранее, чтобы имена хостов не попадали в системные журналы во время приватного просмотра (bug 272190, 279199@main).
2. WebAuthn Related Origin Requests
WebAuthn — веб-стандарт, лежащий в основе passkey. Обычно passkey привязан к единственному домену, но Related Origin Requests позволяет организации использовать один passkey сразу для небольшого набора принадлежащих ей доменов.
Для этого, когда страница запрашивает учётные данные с rpId, отличающимся от собственного источника, клиент сначала загружает https://<rpId>/.well-known/webauthn — JSON-файл со списком источников, которым разрешено использовать этот rpId.
Этот запрос проверки идёт не через сетевой стек браузера. WebKit передаёт церемонии WebAuthn системному сервису учётных данных, который сам выполняет HTTPS-запрос напрямую с устройства, не зная ни о каком прокси, настроенном приложением-хостом. Страница может задать произвольный rpId, и запрос сработает даже без участия пользователя: при mediation: "conditional" интерфейс вообще не появляется.
Та же логика применима к iCloud Private Relay. Поскольку запрос выполняет системный сервис учётных данных, а не Safari, он никогда не попадает в проксируемый Private Relay путь. Конечный сервер в любом случае видит реальный IP-адрес устройства.
Apple анонсировала функцию для iOS 18.0 / Safari 18.0 (сентябрь 2024) в материале WebKit Features in Safari 18.0. Часть реализации со стороны WebKit появилась ранее в том же году (bug 268426, 274592@main) и даже была включена в неактивном виде в iOS 17.4; системный компонент, выполняющий запрос, получил поддержку только в 18.0.
3. WebTransport
WebTransport — низколатентная альтернатива WebSocket. Работает поверх HTTP/3 и QUIC, предлагает несколько независимых потоков плюс ненадёжную доставку дейтаграмм, и может переключаться на HTTP/2 там, где QUIC недоступен.
Вызов new WebTransport(url) открывает QUIC-соединение прямо с устройства. WebKit строит соединение с собственными сетевыми параметрами и никогда не предлагает ему прокси сессии, поэтому сервер видит реальный IP-адрес устройства вместо адреса прокси.
Private Relay здесь тоже не помогает. WebKit строит соединение вне веб-трафика, который проксирует Private Relay, поэтому сервер WebTransport узнаёт реальный IP-адрес устройства даже при включённой Private Relay.
Есть одно исключение: уровень безопасности «Silver» в Onion Browser настраивает WebKit в режим Lockdown Mode, который полностью отключает WebTransport, поэтому пользователи Onion Browser на уровне Silver этой конкретной утечке не подвержены.
Первые следы этого API появились в 2023 году (bug 260810, 267408@main), но оставались отключёнными до декабря 2025 года, когда функцию включили для платформ с достаточной поддержкой Network.framework (bug 303453, 303860@main). Публично она вышла в iOS 26.4 (март 2026); см. WebKit Features for Safari 26.4 и заметки к выпуску Safari 26.4.
Меры, введённые в Psylo 1.3.1
Все три утечки устранены в Psylo 1.3.1:
- Psylo блокирует подсказки
dns-prefetch, так что страница больше не может заставить устройство разрешать контролируемые злоумышленником имена хостов. - WebTransport отключён по умолчанию.
- WebAuthn отключён по умолчанию.
У passkey и WebTransport есть законные сценарии использования, поэтому обе функции можно в любой момент снова включить через переключатели для отдельного «силоса». Это позволяет Psylo оставаться свободным от утечек «из коробки», в то время как пользователям, которым нужна одна из этих функций на конкретном сайте, придётся включить её осознанно, чётко понимая компромисс.