From jameshan.net

Privacy Engineering in a Modern Browser

From October 2025 to April 2026 I interned on Firefox’s privacy team, which works on everything from anti-tracking and fingerprinting protection to privacy-preserving measurement. I wanted to write a bit about the systems we worked on and the problems that are still open.

When you open a news article, the page also tells your browser to fetch things from other companies: tag managers, ad networks, analytics beacons. Each request tells a third party which page you’re on. A company that appears on thousands of sites and recognizes you on each can piece together where you’ve been. The browser sits between you and all of them, so a lot of the work to prevent this happens there.

Blocking

Firefox’s Enhanced Tracking Protection keeps a list of known tracking domains, maintained by Disconnect.⁠The list is sorted into categories: advertising, analytics, social, cryptominers, and fingerprinters. ETP has been on by default since 2019. Standard mode blocks things that rarely break sites, and Strict mode blocks more but breaks more too. As a page loads, every outgoing request is checked against it, and if a request matches, it’s dropped before it leaves the machine, so the tracker never learns that you visited.

The problem is that pages depend on the scripts they load, and a site that expects an analytics object can break when it isn’t there. SmartBlock replaces it with a small local stand-in that behaves enough like the original for the page to work, but doesn’t send anything.⁠A blocked social embed, for example, can be replaced with a placeholder that keeps its text and links, and loads the real thing only if you click. Since Firefox 142, Strict mode also ships compatibility exceptions for trackers whose absence breaks major sites. We can detect more than we can really block without breaking sites.

Partitioning

Blocking only catches trackers that are already on the list, so Firefox also partitions storage for the ones that aren’t. Total Cookie Protection, on by default since 2022, gives every site its own cookie jar and storage, so a tracker embedded on two sites can’t use the same storage to recognize you on both.⁠Partitioning covers more than cookies: local storage, caches, and other state trackers use as makeshift cookies. CHIPS (Cookies Having Independent Partitioned State), the one piece of Chrome’s cookie plan that survived, lets a site opt a single cookie into a partitioned jar. Firefox supports it too.

Safari partitions too. Chrome still allows third-party cookies by default, after deciding in April 2025 not to phase them out.

Trackers also get around partitioning through navigation. A tracker can route your click through its own domain for a moment, where it is first party and can read its cookies, then send you on to the page you wanted. Or it can just add an identifier to the link itself. Firefox’s bounce tracking protection clears storage for sites you only ever pass through, and query stripping removes known tracking parameters from URLs.⁠Both ship in Strict mode and Private Browsing. Brave goes further and skips known bounce domains entirely.

Fingerprinting

Fingerprinting doesn’t need any storage. A script can ask for things like screen size, fonts, time zone, how your GPU draws an image. Any one of these usually isn’t enough to identify you, but together they often are, and there’s nothing you can really clear to reset them.

There are two main ways to deal with this. You can make everyone look the same, like Tor Browser does, which works well but breaks a lot of sites, and it only works if enough other people are using it too. Or you can add a little noise per site so the same person looks different on each, and a tracker can’t match you across them, though an attacker who sees you often can average the noise away. Firefox mostly does the second. Firefox 145 extended it to graphics, fonts, and hardware details, and roughly halved the share of users who look unique in Private Browsing and Strict mode.⁠Brave removed its strictest fingerprinting mode in 2024: under 0.5% of users turned it on, it broke sites, and using it made those users stand out. You need enough other people using the same protections for this to work. Separately, Google’s ad policy has permitted fingerprinting since February 2025.

Measuring what you’ve prevented

Most of this isn’t visible to the person using the browser. We worked on showing people what their browser does for them, but it’s hard to report on something you’ve prevented from happening. A blocked request never returns, so the browser never learns what it saved. We estimated the cost with a small model trained on crawls where those requests were allowed to complete.⁠The target was a bit strange. About 40% of tracker responses are zero bytes and a few are 100 KB script bundles. Insurance claims have a similar distribution, and using Tweedie, the loss function actuaries use for this, cut our error by about 23%.

Aggregating without seeing

For measurements across users, Firefox uses Prio through ISRG’s Divvi Up: each browser splits a measurement into random-looking shares and sends one to each of two servers. Neither server can learn anything from its shares alone, and only the sum comes out. Reports travel through an Oblivious HTTP relay, a go-between that forwards encrypted reports so that no single party sees both who sent a report and what it says.⁠The relay sees your IP address but not the report. The server behind it sees the report but not your IP address. It’s only one hop, unlike Tor. Divvi Up has processed about 4.5 billion reports this way, with Firefox as its main deployment.

The cryptography works, but you still have to trust that the two servers won’t collude. That depends on the organizations running them. There is a lot of this in privacy work, where you replace “we won’t look” with something else you have to trust. Federated learning and private cloud inference both rely on secure hardware enclaves, which cheap physical attacks are now breaking.

Differential privacy

Differential privacy adds calibrated noise so the output barely changes whether or not any one person is in the data, and ε bounds how much.⁠Formally, for any output, its probability with you in the data is at most e^ε times its probability without you. A smaller ε gives a stronger guarantee. The number is precise, but to know what it actually guarantees you need details that deployments don’t usually report.

Real deployments range from ε ≈ 0.15 per query at LinkedIn to nearly 50 for Census detailed tables. Google’s VaultGemma has ε ≤ 2, but per 1,024-token sequence, not per person. Models trained to the same ε can memorize very differently, and much DP training code reports ε for a sampling scheme it doesn’t use, understating the real value. It’s hard to tell much from ε alone without its unit, the lifetime budget, and the accountant used to calculate it.

Advertising

For ads, you also have to work with privacy budgets across parties who don’t trust each other. In October 2025 Chrome retired most of the Privacy Sandbox. What’s left on the standards track is the W3C Attribution API, edited by Mozilla, Google, and Meta: the browser matches ads to purchases on the device, reports go through the same two-server aggregation, and each site gets a weekly privacy budget. Big Bird, a 2025 research system prototyped in Firefox, shows those per-site budgets break when sites adapt to each other’s results.

There were also problems with consent. Firefox’s own Privacy-Preserving Attribution shipped on by default in Firefox 128, drew a complaint that it should have been opt-in, and was removed without ever being activated.⁠Mozilla’s support page now describes it as a historical reference: the experiment ran too late to inform the W3C work it was meant to feed.

Evaluating models you can’t watch

Browsers are also shipping local models now. Firefox runs PDF alt-text, tab grouping, and link previews on the device. Running them locally means you don’t need to collect the data, but then if nothing leaves the device, how do you know the model works? For now this is mostly done with synthetic data. Firefox’s tab grouping was trained and evaluated on pages a larger model generated for invented users. No browser has published how it measures the real-world quality of its local models.⁠Chrome goes further and exposes its on-device model to web pages through a Prompt API. Mozilla’s standards position on it is negative, mainly because sites would come to depend on one vendor’s model.

What’s open

There is still a lot to work on here. Fingerprinting defenses that hold up when an attacker sees you often, privacy budgets shared across parties who don’t trust each other, trust roots that hold up when someone has physical access. And how to tell whether a model works when you’ve promised not to watch it.