Публичная страница может незаметно опрашивать 127.0.0.1 и роутер, замеряя время ответа, чтобы понять, что работает в вашей сети. Вот что её останавливает.
Обычная вкладка, открытая на обычном публичном сайте, может попросить ваш браузер отправить запросы на 127.0.0.1 и на LAN-адрес вашего роутера — скажем, 192.168.1.1 — и замерить, сколько времени занимает ответ на каждый из них. Ей вообще не нужно читать тело ответа — правила кросс-доменных запросов и так это блокируют. Достаточно знать, ответило ли что-то быстро, медленно или не ответило вовсе. Этого хватает, чтобы построить карту того, что работает в сети за вашим единственным публичным IP-адресом, и до совсем недавнего времени ничто в браузере не мешало странице этим заниматься.
Ключевые выводы
- Публичная веб-страница может отправлять запросы на
localhostи на приватные LAN-адреса вроде192.168.x.xиз обычного JavaScript — подойдутfetch(), тег<img>или соединение WebSocket, и ни один из этих способов по умолчанию не требует особых разрешений. - Странице не нужно читать ответ. Времени отклика (ответил ли адрес и насколько быстро) и исхода соединения (открыто, отклонено или превышен таймаут) достаточно, чтобы понять, слушает ли что-то на данном локальном адресе и порту.
- Утекает информация о вашем устройстве и сети, а не о браузере: dev-сервер на порту 3000, медиасервер, десктопный агент какого-то производителя или конкретная модель роутера — факты стабильные, трудноизменяемые и идентифицирующие совсем иначе, чем canvas- или font-отпечаток.
- Та же форма запроса — ещё и вектор CSRF против роутеров и локальных админ-панелей, которые никогда не рассчитывались на запросы от случайной публичной страницы.
- Решение Chrome, Local Network Access, — это обращённый к пользователю запрос разрешения, появившийся в Chrome 142; он заменил более ранний и куда менее заметный подход под названием Private Network Access, который спрашивал согласия не у пользователя, а у локального устройства.
Что страница может сделать на самом деле
Здесь не требуется никаких экзотических браузерных API. Страница, которая хочет прощупать вашу сеть, может выпустить пачку обычных запросов — вызов fetch() к http://127.0.0.1:3000/, элемент изображения, указывающий на http://192.168.1.1/, или открытие соединения WebSocket к ws://127.0.0.1:8080 — и понаблюдать, что произойдёт дальше. Политика одного источника не даёт странице прочитать содержимое ответа, но не может скрыть, разрешился ли промис fetch() или был отклонён, сколько времени элементу изображения понадобилось, чтобы выстрелить событием load или error, или достиг ли WebSocket состояния onopen вместо onerror. Замерьте время для пачки таких запросов по диапазону распространённых портов на 127.0.0.1 и в приватных диапазонах адресов (192.168.0.0/16, 10.0.0.0/8) — и сама картина успехов, отказов и таймаутов уже становится результатом сканирования, причём ни один байт тела ответа так и не покидает локальную сеть.
Что именно утекает: факт о вашем устройстве, а не о браузере
Большая часть того, что BrowserInsight относит к фингерпринтингу — вывод canvas, установленные шрифты, строки рендерера WebGL, — описывает ваш браузер и его движок отрисовки. Сканирование локальной сети описывает нечто иное: какое программное обеспечение реально работает на физической машине и в сегменте сети, в котором она находится. Ответ на порту 3000 или 8080 часто означает локальный сервер разработчика. Устройство, отвечающее по адресу вашего роутера так, что это совпадает с известной сигнатурой админ-панели, выдаёт модель роутера, иногда вплоть до семейства прошивки. Ответ на порту, который использует десктопный агент синхронизации или медиасервер конкретного производителя, выдаёт присутствие этого ПО в вашей LAN — независимо от того, работает ли оно в той вкладке, на которую вы сейчас смотрите. Ничего из этого не берётся из заголовка или JavaScript API, прямо сообщающего странице «у пользователя установлено X», — всё выводится исключительно из того, какие локальные «двери» ответили на стук. Это делает такой сигнал по-настоящему иным, чем энтропия фингерпринтинга, которую обычно обсуждает руководство по фингерпринтингу браузера на этом сайте, и он даёт иную форму множества анонимности: он не столько отличает вас от других посетителей той же страницы, сколько картирует именно вашу домашнюю или офисную сеть.
Другая половина проблемы: CSRF против вашего роутера
Фингерпринтинг — не единственная причина, по которой это исправили. Та же форма запроса — публичная страница, дотягивающаяся до приватного адреса, к которому её никто не приглашал, — это ещё и способ, которым работают атаки межсайтовой подделки запроса (CSRF) против роутеров и локальных админ-панелей. Веб-интерфейс роутера или привязанная к локальному адресу админ-панель NAS или IoT-устройства часто строятся на негласном допущении, что достучаться до них может только тот, кто уже находится в LAN. У них нет причин ожидать запроса, подделанного JavaScript-ом с совершенно постороннего публичного сайта. Объясняя, зачем нужно новое разрешение, Chrome одной фразой называет обе темы этой статьи: оно должно «защитить пользователей от атак межсайтовой подделки запроса (CSRF), нацеленных на роутеры и другие устройства в приватных сетях, и уменьшить возможность сайтов использовать такие запросы для снятия отпечатка локальной сети пользователя». Один и тот же запрос — две разные вещи, которые злоумышленник может с ним сделать.
История защиты: сначала preflight, потом запрос разрешения
Первой попыткой Chrome закрыть эту брешь был Private Network Access, и прежде чем говорить о том, что пришло ей на смену, стоит понять, почему она не сработала до конца. Ключевая идея PNA состояла в том, чтобы спрятать запросы с публичных страниц к целям в приватной сети за CORS-preflight: перед тем как отправить настоящий запрос, браузер посылал запрос OPTIONS, спрашивая у целевого устройства, готово ли оно явно дать согласие, ответив заголовком Access-Control-Allow-Private-Network: true. В теории это отдаёт решение в руки того, кто управляет локальным устройством, — разумный замысел. На практике дело так и не вышло из стадии эксперимента. Разбор preflight от Chrome фиксирует откат после проблем, вскрывшихся в Chrome 98, а затем возвращение в Chrome 104 в намеренно беззубом виде: провалившийся preflight лишь выводил предупреждение в DevTools, а настоящий запрос всё равно уходил, причём тайм-аут самого preflight ограничили 200 миллисекундами, чтобы он не тормозил загрузку страниц. Настоящее принудительное включение наметили «не раньше Chrome 113» и прямо обусловили тем, что данные о совместимости покажут достаточную безопасность изменения. Оно так и не состоялось — собственный анонс Local Network Access от Chrome фиксирует, что подход с preflight поставили на паузу.
Соседней части PNA повезло не больше. Обновление Chrome по PNA отслеживает вторую линию этой работы — запрет запросов в приватную сеть с небезопасных публичных страниц, — которую переносили с Chrome 92 на 93, а после новых отзывов разработчиков и на 94; при этом deprecation trial, позволявший затронутым сайтам продолжать работать, продлевали снова и снова (до 113, затем до 116), пока он окончательно не истёк в Chrome 117.
В этом и заключается главный урок, который преподал PNA: спрашивать согласия у целевого устройства не работает, если большинство устройств в сетях реальных людей — роутеры, принтеры, хабы умного дома, сетевые хранилища — никогда не получат прошивку, которая научит их это согласие давать. Сколько ни переноси срок, это не изменится, потому что железо находится не на той стороне срока.
Почему запрос разрешения побеждает preflight
Local Network Access — LNA — это ответ Chrome, и он переносит решение с недостижимого устройства на человека, который на самом деле сидит за клавиатурой. Вместо того чтобы просить роутер или dev-сервер дать согласие через заголовок, который те никогда не отправят, браузер теперь показывает пользователю запрос — формулировка самого Chrome звучит как «Искать устройства в локальной сети и подключаться к ним» — при первой попытке публичной страницы обратиться к приватному адресу. Пользователь может разрешить это один раз, если доверяет сайту (панели умного дома это разрешение действительно нужно), или просто отклонить запрос — а для подавляющего большинства страниц нет вообще никакой законной причины прощупывать домашнюю сеть. Это переворачивает узкое место: вместо того чтобы ждать, пока миллионы неподдерживаемых устройств реализуют новый заголовок, Chrome достаточно, чтобы проверку выполнял сам браузер, а решение каждый раз принимает владелец сети.
Функция вышла в Chrome 142; до этого, начиная с Chrome 138, её можно было включить самому — флагом chrome://flags#local-network-access-check. При этом Chrome определяет её охват уже, чем «любой запрос на локальный адрес»: запросом в локальную сеть считается запрос из публичной сети к локальной сети или к loopback. Сюда попадают приватные диапазоны RFC 1918 (например, 192.168.0.0/16), link-local адреса (169.254.0.0/16 и fe80::/10), уникальные локальные адреса IPv6 (fc00::/7), loopback (127.0.0.0/8 и ::1) и хосты .local — именно то адресное пространство, которое стал бы обходить сканирующий скрипт. Чего защита пока не покрывает — так это страницу, уже отданную с приватного адреса и тянущуюся дальше вглубь, к loopback; Chrome заявляет, что планирует позже распространить её на все кросс-доменные запросы в локальную сеть.
Что видит читатель сегодня
Если у вас свежий Chrome и сайт пытается обратиться к адресу в вашей LAN, вы увидите запрос разрешения, а не молчаливый запрос. Большинство сайтов, которые вы посещаете, никогда его не вызовут, потому что у них нет причин говорить с вашим роутером или локальным dev-сервером — если же какой-то сайт это делает, а вы не понимаете зачем, отклонить запрос — безопасный выбор по умолчанию. Это внедрение пока ведёт именно Chrome, а не весь веб: не стоит считать, что тот же запрос или та же защита есть в любом браузере только потому, что вы видели это в одном из них. Если хотите узнать, что ваш текущий браузер и сетевая конфигурация раскрывают за пределами этого конкретного механизма, проверка отпечатка от BrowserInsight охватывает куда более широкий набор сигналов уровня устройства и браузера, которые страница может считать вообще без единого запроса разрешения.
Как это соотносится с другими темами приватности на сайте
Это легко смешать с другими, не связанными техниками отслеживания, которые оказываются по соседству на этом сайте, так что стоит явно провести границу: CSS-фингерпринтинг — это таблица стилей, выводящая характеристики устройства вроде тёмной темы или типа указателя, без единого сетевого запроса. Session replay — это скрипт, записывающий, что вы делаете внутри страницы, на которой уже находитесь. Приватность браузерных расширений — про установленные надстройки, читающие данные страницы, а не про сам браузер, превращённый в сканер сети. Постоянные ID посетителя — про повторное опознавание вас между визитами, а не про картирование вашей LAN. Этот материал — конкретно про то, как браузер превращается в зонд против приватной сети, в которой находится машина, — механизм, отличный от всех четырёх выше, хотя их и объединяет общая тема: страница узнаёт о вас больше, чем вы согласились раскрыть.
Часто задаваемые вопросы
Это касается всех браузеров или только Chrome?
Local Network Access — функция Chromium, вышедшая в Chrome 142. Поддержка в других движках различается и меняется со временем, так что лучше свериться с примечаниями к выпуску конкретно вашего браузера, а не считать защиту повсеместной — сами базовые техники запроса (fetch, <img>, WebSocket) одинаково работают в любом браузере, пока этот браузер их специально не ограничит.
Может ли сайт просканировать мою сеть незаметно для меня?
До появления Local Network Access — да: скрипт, прощупывающий десятки локальных адресов и портов, вообще не создаёт видимого интерфейса; единственный след оставался на вкладке «Сеть» в инструментах разработчика, куда почти никто не заглядывает. Именно эта незаметность, даже больше, чем сам технический механизм, и сделала оправданным решение именно через запрос разрешения, а не оставлять всё на добросовестность каждого отдельного сайта.
Это то же самое, что утечка локального IP-адреса через WebRTC?
Нет, хотя оба явления затрагивают вашу локальную сеть. Сбор ICE-кандидатов в WebRTC может раскрыть ваш локальный IP-адрес как побочный эффект установления peer-соединения. Здесь всё иначе: страница активно отправляет запросы на адреса в вашей сети и считывает время отклика и исход, а не попутно узнаёт один-единственный адрес вашей собственной машины.
Нужно ли мне что-то делать, чтобы быть защищённым?
Если у вас актуальная версия Chrome, запрос разрешения включён по умолчанию — специальной настройки для этого нет. Просто отклоняйте запрос на сайтах, у которых нет очевидной причины обращаться к вашей локальной сети, — так же, как вы отнеслись бы к любому запросу разрешения, не соответствующему заявленному назначению сайта.
Почему Private Network Access так долго превращался в Local Network Access?
Потому что изначальный замысел исходил из того, что локальные устройства можно обновить так, чтобы они умели отвечать на запрос нового типа, а большинство потребительских роутеров, принтеров и IoT-устройств фактически никогда не получают обновлений после выпуска. Сроки принудительного включения годами откладывались, прежде чем в Chrome пришли к выводу, что решение должно целиком жить в браузере и в решении пользователя, а не зависеть от сотрудничества с железом, которое так и не подключится к процессу.
Заключение
Публичная веб-страница, дотягивающаяся до 127.0.0.1 и до LAN-адреса вашего роутера, — не гипотетический сценарий: это запрос, который ваш браузер охотно отправит, замеренный ровно настолько тщательно, чтобы составить карту того, что слушает сеть, — и всё это без необходимости прочитать хоть байт ответа. Private Network Access пытался закрыть эту брешь, спрашивая разрешения у недостижимых локальных устройств, и потратил годы, чтобы выяснить: это не масштабируется. Local Network Access вместо этого спрашивает вас — запросом разрешения, появившимся в Chrome 142. Этот механизм стоит знать, даже если вы сами никогда не увидите запрос: это ещё один пример того, как функция браузера, на первый взгляд не связанная с вашей идентичностью — обычный сетевой запрос, — на деле описывает ваше устройство и вашу сеть так же точно, как любой скрипт фингерпринтинга.
Рекомендуем прочитать:
- Цифровой отпечаток браузера: как защитить приватность
- CSS-фингерпринтинг: отслеживание без JavaScript
- Session Replay: как сайты записывают каждое ваше действие
- Visitor ID: как он переживает инкогнито, VPN и кеш
- Угрозы приватности от расширений браузера
- Энтропия отпечатка браузера и множество анонимности


