The Localhost Boundary That Became an Identity Bridge

Bridges to Self: Silent Web-to-App Tracking on Mobile via Localhost examines how Meta and Yandex used a connection that looked local to join two identities that users and platforms normally expect to remain separate. The central question is not simply whether a browser can contact localhost; it is whether a web script can use that contact to hand a web identifier to a native app and then benefit from the app’s longer-lived identity. Understanding that distinction gives the reader a way to judge the paper’s evidence, the privacy controls it tested, and the defenses that followed.

A local request with a non-local consequence

A phone can run many services at once. A browser displays a web page in one process, while a native app runs in another. If the page sends a request to a service listening on the same device, the request may never leave the phone. It is tempting to treat that as a small technical detail: the network destination is local, so the privacy consequence should be local too.

The paper shows why that intuition fails. A page can carry a pseudonymous web value—a cookie or another identifier—to a native application. The app may already know a user through an account, an advertising identifier, or another device-level value. If the app associates the two and sends the result to its operator, the local request has created a relationship that is not local at all. The web activity can now be recognized in a native ecosystem, and the native identity can help make later web activity persistent.

That is the “bridge” in the paper’s title. The bridge does not require the browser to read another website’s storage or the app to open the browser’s private files. The two contexts can remain separately sandboxed while an allowed communication path carries information between them. Isolation of code and storage is therefore not the same as isolation of identity relationships.

flowchart LR W["Public web page and embedded tracker"] --> I["Web identifier or event data"] I --> L["Localhost or related local channel"] L --> A["Native mobile app"] A --> N["Longer-lived native identifier"] N --> C["Operator back end"] C --> M["Cross-context identity match"] B1["Browser and app isolation boundaries"] -.-> L

The study attributes large-scale observed deployments to Meta and Yandex. That attribution matters because the risk depends on coordination. A local listener in an obscure utility is not automatically the same thing as a tracking campaign. The actors examined in the paper had both sides of the equation: web scripts distributed across many sites and native apps installed by many people. Their reach made it likely that the script and the matching app would be present on the same phone.

Why the expected protections were not enough

Web browsers and mobile operating systems do provide real isolation. The browser’s Same-Origin Policy is designed to stop one origin from directly reading another origin’s data or execution context. Modern browsers also limit third-party tracking with cookie restrictions and storage partitioning. Android gives applications separate Linux user IDs and sandboxes their code, memory, and storage. Deliberate app-to-app communication is expected to use defined inter-process communication mechanisms, often with permissions.

Those protections answer different questions from the one raised by the paper. The Same-Origin Policy asks whether one web origin can inspect another web origin. An app sandbox asks whether one application can directly read another application’s private state. Neither rule, by itself, asks whether public web content should be allowed to send data to a process that happens to be listening on the same device.

Historically, localhost received a particularly permissive treatment. Web standards classify it as a potentially trustworthy origin, even though a service on the loopback interface need not have the same remote authentication or encryption properties as a normal HTTPS service. Before Local Network Access protections were deployed, browsers could allow JavaScript APIs to reach local services without a user prompt or an operating-system decision at the moment of access. From the browser’s point of view, the page was using a permitted web API. From the app’s point of view, it was receiving a socket request. The identity transfer fell between those viewpoints.

This explains why several familiar privacy controls were not sufficient in the paper’s tests. Clearing a cookie can remove a web-side state, but it cannot necessarily erase a copy already handed to an app. Resetting an advertising identifier does not automatically delete a server-side relationship that was built from an earlier value. A VPN can change how traffic reaches the internet, but it does not by itself stop two processes on the same phone from using a local interface. Work and personal profiles can separate their normal stores and permissions while still leaving a local communication path that the tested proof of concept could use across profiles.

The issue is therefore not that every protection failed everywhere. It is that each protection governed a different boundary. A control for browser storage cannot be assumed to control native identity. A control for remote routing cannot be assumed to control loopback. A control for process memory cannot be assumed to control a socket deliberately made reachable to another context.

What the study is asking us to examine

The paper’s evidence is built around that boundary problem. The researchers combined large web crawls with systematic Android app analysis because either side alone could produce a misleading picture. A browser crawl can reveal a request to localhost without identifying the native process that answered it. App analysis can find a listener without showing which web scripts activate it or what data arrives. Connecting the two is what turns a suspicious local request into evidence of a coordinated bridge.

The reported scale makes the question consequential. In April 2025 Android crawls from US and EU vantage points, the researchers found WebRTC localhost communications on 17,368 US sites and 15,819 EU sites. They found HTTP(S) localhost communications on 1,379 US sites and 1,327 EU sites. Meta accounted for about 99% of the observed WebRTC cases, while Yandex accounted for about 95% of the observed HTTP(S) cases. These numbers describe sites observed under the study’s conditions, not the number of affected people or a complete count of all websites.

The consent experiment adds a second dimension. On sites where the researchers had seen the behavior, the scripts often initiated localhost communication before the crawler accepted a consent banner: 75.8% of the EU sites and 78.2% of the US sites for Meta Pixel, and 84.4% and 83.5% for Yandex Metrica. That result is a technical observation about when the communication began. It raises serious questions about transparency and user choice, but it is not by itself a universal legal ruling about every site or jurisdiction.

The study also records a sharp fall in observed activity after public disclosure. That change supports the conclusion that the researchers had found active, changeable deployments rather than an abstract protocol possibility. It does not prove that every related implementation disappeared or that a future actor could not reproduce the pattern. The paper explicitly describes its measurements as conservative lower bounds. Bot detection, limited visits, execution timing, remote configuration, and the difficulty of exercising every possible website-app pair all constrain what the counts can establish.

That combination of scale and uncertainty is important. The paper is strong enough to show that the bridge was technically feasible, deployed in the wild by major actors, and capable of crossing boundaries that users reasonably expected to matter. It is not a license to turn every localhost request into evidence of surveillance, or to treat one tested app version as a permanent description of an entire platform.

The question that follows from the finding

The first practical lesson is to ask what crosses the boundary, who owns the state on each side, and where the two identity systems are joined. A local connection used for development or an OAuth callback may have a visible purpose and a narrow data flow. A silent tracker may use the same general interface while carrying a web identifier into a native account system and forwarding the result to a remote operator. Location alone cannot tell those cases apart.

The second lesson is about defense. A domain blocklist may stop a known tracker, but it does not necessarily govern the local channel. A restricted-port rule may interrupt one implementation, but a different port or protocol can preserve the same relationship. A permission system must account for the ways browsers can reach local services, including the protocol and side-channel details that make a connection possible. Chrome’s Local Network Access work is an important response because it introduces user mediation for public-web requests to local or loopback destinations. The paper nevertheless examines gaps in protocol coverage and address classification, showing why a single permission label is not the end of the design problem.

The series that follows keeps the named study in view while moving from its isolation assumptions to the Yandex and Meta cases, the measurements, and the platform response. The central question remains stable: when a local interface can carry identity between web and native contexts, which boundary is actually being protected? The answer cannot be found by looking only at a cookie, a port, or an app sandbox. It requires following the relationship across all three contexts—the page, the native process, and the back end that receives the match.

References