Hacker News new | ask | show | jobs
by Timja 1164 days ago
There is no way to escape fingerprinting.

Just one example: A script which runs many different types of computations. Each computation will take a certain amount of time depending on your hardware and software. So you will get a fingerprint like this:

    computation 1: **
    computation 2: ****
    computation 3: **********
    computation 4: **
    computation 5: **************
    computation 6: ************
    computation 7: *********
    etc
There is no way to avoid this. You can make the fingerprint more noisy by doing random waits. But thats all.
4 comments

Just put WebGL/WebGPU behind permission and the problem is solved. I don't understand why highly paid Google and Firefox developers cannot understand such a simple idea.
For a user to correctly answer a permissions dialog, they need to learn programming and read all the source code of the application. To say nothing of the negative effects of permission dialog fatigue.

In practice, no-one who answers a web permissions dialog truly knows if they have made the correct answer.

Asking the user a question they realistically can't answer correctly is not a solution. It's giving up on the problem.

I think browsers should distinguish more aggressively between "web application", "web site", and "user hostile web site".

Many APIs should be gated behind being a web application. This itself could be a permission dialog already, with a big warning that this enables tracking and "no reputable web site will ask for it unless it is clear why this permission is needed - in doubt, choose no".

Collect opt-in telemetry. Web sites that claim to be a web application but keep getting denied can then be reclassified as hostile web sites, at which point they not only lose the ability to annoy users with web app permission prompts, but also other privileges that web sites don't need.

Clearly if we knew how to perfectly identify user hostile websites we'd not need permissions dialogs at all.

Distinguishing between site and app, e.g. via an installation process, is equivalent to a permissions dialog, except that you're now advocating for one giant permission dialog instead of fine-grained ones, which seems like a step backwards.

Yes, if we knew how to do it perfectly, we wouldn't need them. But we can identify some known-good and known-bad cases with high confidence. My proposal mainly addresses the "fatigue" aspect: it allows apps to use some of the more powerful features without letting every web site use them, and it prevents random web sites from declaring themselves an app and spamming users with the permission request just so they can abuse the users more.

The new permission dialog wouldn't grant all of the finer-grained permissions - it would be a prerequisite to requesting them in the first place.

SafeBrowsing filters out the known bad ones.

Curating known good would equate to some sort of app store. There are probably initiatives to make one for web apps, but it kind of makes me sad to think of applying that to the web, which is supposed to be a free and open commons (although I suppose Google already de facto controls enough of it to be considered a bit of a gatekeeper).

Making the user the arbiter of "known good", ie reliance on permissions dialogs, is not perfect but it's what we have. Yet I fail to see how your proposal of "just add ANOTHER dialog" improves the situation.

Do you have something specific in mind with your opening paragraph?

Because defining what is a web site and what's an app, strikes me as particularly impractical idea. You correctly point out that yes, there are a number of powerful APIs that should be behind permissions. But there are a number of permissions already, so we need to start bundling them and also figure out how to present all this to the regular user.

Frankly, I wouldn't know where to begin with all this.

News sites are a particular category that I expect to spam people with permission prompts, as they did when notifications became a thing. Without the deterrent of possibly landing in the naughty box, they'd all do it. With it, I still expect some of them to try until they land in the box.
> In practice, no-one who answers a web permissions dialog truly knows if they have made the correct answer.

Counterpoint: if webpage with latest news (for example) immediately asks me to allow notification, access to webcamera and location I definitely know what is correct answer to these dialogs.

"Do you want to allow example.com to send you notifications" is way more understandable to a layperson than "do you want to allow access to WebGPU" or "do you want to allow access to your graphics card". Especially because they would still have access to canvas and WebGL.

Permission prompts are a HUGE user education issue and also a fatigue issue. Rendering is widely used on websites so if users get the prompt constantly they're going to tune it out.

You can always word things in a way that the user understands.

> Especially because they would still have access to canvas and WebGL.

Those should also be behind a (or the same) permission prompt.

They don't need to learn programming. Just write that this technology can be used for displaying 3D graphics and fingerprinting and let user decide whether they take the risk.
They're going to be confused if you say "display 3D graphics", because canvas and WebGL will still work. The website will just be laggier and burn their battery faster. That's not going to make sense to them.

"Fingerprinting" is a better approach to the messaging, but is also going to be confusing since if you take that approach, almost all modern permissions are fingerprinting permissions, so now you have the problem of "okay, this website requires fingerprinting class A but not fingerprinting class B" and we expect an ordinary user to understand that somehow?

Most of them will say, "I need to see this site, who cares about fingerprints." Some will notice that they're on their screen anyway, a few will know what it's all about.

Maybe "it can be used to display 3D graphics and to track you", but I expect that most people will shrug and go on.

You could maybe display the request in the canvas instead of a popup. If the user can't see it, they'll never say yes.
Just put WebGL/WebGPU behind permission and the problem is solved.

Just put WebUSB behind permission and the problem is solved.

Just put WebHID behind permission and the problem is solved.

Just put WebMIDI behind permission and the problem is solved.

Just put Filesystem Access behind permission and the problem is solved.

Just put Sensors behind permission and the problem is solved.

Just put Location behind permission and the problem is solved.

Just put Camera behind permission and the problem is solved.

Just put ...

I don't understand why highly paid Google and Firefox developers cannot understand such a simple idea.

I can't tell whether you're kidding or not, but this is exactly the path Firefox was advocating: https://blog.karimratib.me/2022/04/23/firefox-webmidi.html

The page implies it no longer requires permissions, but I just tested and you definitely get a permissions popup, just a different one.

WebHID, WebUSB and Filesystem Access are IIRC, "considered harmful" so they won't get implemented. And Sensor support was removed after sites started abusing battery APIs.

> I can't tell whether you're kidding or not,

I'm not. It's a bit of a sarcasm (?) listing a subset of APIs that browsers implement (or push forward against objections like hardware APIs) and that all require some sort of permission.

> but this is exactly the path Firefox was advocating

Originally? Perhaps. Since then Firefox's stance is very much "we can't just pile on more and more permissions for every API because we can't properly explain to the user what the hell is going on, and permission fatigue is a thing"

Everything except WebGL and WebGPU allows the system to change more state than what is rendered on a screen.

Users already expect browsers to change screen contents. That's why WebGPU / WebGL aren't behind a permission block (any moreso than "show images" should be... Hey, remember back in the day when that was a thing?).

Yes please
Saturating the user with permissions requests for every single website they visit is a dead-end idea. We have decades of browser development and UI design history to show that if you saturate the user with nag prompts that don't mean anything to them, they will just mechanically click yes or no (whichever option makes the website work).
Permission popups can be replaced with an additional permission toolbar or with a button in the address bar user needs to click. This way they won't be annoying and won't require a click to dismiss.
Like the site settings page on Chrome, which is in the address bar (clicking the lock icon)? You can set the permissions (including defaults) for like 50 of these APIs.
You can display only permissions that a page requests, starting from most important ones.

For example, toolbar could look like:

Enable: [ location ] [ camera ] [ fingerprinting via canvas ] ...

We already have extensions for websites that spam the user with unwanted popups and other displays. Those just need to be extended to cover permission abuse and be included by default in all webbrowsers.
I do this since forever, but I have to give explicit permission to load and run JS, which solves a lot of other problems as well. Letting any site just willy-nilly load code from whereever and run it on your machine is insane, and it's well worth the effort to manually whitelist every site.
uMatrix was and unfortunately still is the best interface for fine-grained opt-in permissions.
Look to the cookie fatigue fiasco for how that might turn out. This simple idea is not always the right one.
> [ ] Always choose this option.
Why fiasco?
They are highly paid enough to not work on it and smart enough to thwart suggestions like this with “permission overload issue”.

But more frankly, fingerprinting is a whack a mole issue and if it were a real security problem, it would slow feature advancements.

And fingerprinting is too unreliable for any real world use.

It's not that they don't understand it, it's that they don't want the average user to have a convenient way to control this setting. Prompting the user for permission would give the user a very convenient way to keep it disabled for most websites. It's as simple as that.

Think about it this way: Which is more tedious: going into the settings and enabling and disabling webGPU every time you need it or a popup? Which way would see you keeping it enabled?

Its tyranny of the default with an extra twist :)

> why highly paid Google ... developers

"Completely co-incidentally", it's in Google's best interest to be able to fingerprint everyone.

So, changing it to actually be privacy friendly while they have the lion's share of the market doesn't seem like it's going to happen without some major external intervention. :/

It's running on Chrome. Google doesn't need fingerprinting. By making it harder for others to fingerprint it actually cements Google position in the ad market.
> It's running on Chrome. Google doesn't need fingerprinting.

Are you saying that because you reckon everyone using a Chromium based browser logs into a Google account?

"Be kind. Don't be snarky. Converse curiously. Please don't sneer"

HN Guidelines

https://news.ycombinator.com/newsguidelines.html

They probably can understand these concepts, but privacy and anonymity are not their main priorities.
Just don’t use Chrome. There are plenty of alternative web browsers you can choose that are more privacy oriented. You are not Chrome’s customer unless you pay for it - or you have 100% money back guarantee. Demanding features on free product is never going to go anywhere.
You can reduce clock precision, which has already been done to mitigate speculative execution attacks. You can delay network requests to prevent the JS from using the server as a more precise clock. In addition to random delays, you can quantize execution times by only responding in 100ms increments, for example. You can do lots of things to mitigate fingerprinting, if not completely prevent it.

But then you could also just omit features that have no reason to exist in the first place.

Or everybody can just buy the same (i)Phone :)
You only get fingerprinting from your method if the variation of the “fingerprint“ between two different runs by the same user is lower than the difference you get between two different users. This is far from obvious since it depends a lot on the workload running on the machine at the time.

I'm not aware of a single fingerprinting tool that primarily use this king of timing attack rather than more traditional fingerprinting methods.

Not sure if the workload makes a difference.

We would have to make examples of what Computation1 is and what Computation2 is to make a prediction if certain types of workloads will impact the ratio of their performance.

Example:

    s=performance.now();
    r=0;
    for (i=0; i<1000000; i++) r+=1;
    t1=performance.now()-s;

    s=performance.now();
    r=0;
    for (i=0; i<1000000; i++) r+="bladibla".match(/bla/)[0].length;
    t2=performance.now()-s;

    console.log("Ratio: " + t2/t1);
For me, the ratio is consistently larger in Chrome than in Firefox. Which workload would reverse that?
Fingerprinting in the usual sense the term isn't about distinguishing Chrome from Firefox, it's about distinguishing user A from user B, … user X reliably in order to be able to track the user across website and navigation sessions.

Your example is unlikely to get you far.

Edit: in a quick test, I got a range between 8 and 49 in Chrome, and between 1.27 and 51 (!) on Firefox, on the same computer, the results are very noisy.

Chrome and Firefox here are an example for "Two users who use exactly the same hardware but different software".

To distinguish between users between of a larger set, you do more such tests and add them all together. Each test adding a few bits of information.

To make the above code more reliable, you can measure the ratio multiple times:

https://jsfiddle.net/dov1zqtL/

I get 9-10 in Firefox and 3-4 in Chrome very reliably when measuring it 10 times.

> Chrome and Firefox here are an example for "Two users who use exactly the same hardware but different software".

But it's also the most pathological example one can think of, yet the results are extremely noisy (while being very costly, which means you won't be able to make a big number of such test without dramatically affecting the user's ability to just browse your website).

It's possible to have the runtime execute the computations in fixed time across platforms.
Sure. And nobody actually wants that, because it would be so restrictive in practice that you might as well just limit yourself to plain text.

The horse bolted long ago; there's little sense in trying to prevent future web platform features from enabling fingerprinting, because the existing surface that enables it is way too big to do anything meaningful about it.

Here are a couple of more constructive things to do:

- Campaign to make fingerprinting illegal in as many jurisdictions as possible. This addresses the big "legitimate" companies.

- Use some combination of allow-listing, deny-listing, and "grey-listing" to lock down what untrusted websites can do with your browser. I'm sure I've seen extensions and Pi-hole type products for this. You could even stop your browser from sending anything to untrusted sites except simple GET requests to pages that show up on Google. (I.e. make it harder for them to smuggle information back to the server.)

- Support projects like the Internet Archive that enable viewing large parts of the web without ever making a request to the original server.

This would essentially mean that every computation would have to run as slow as the slowest supported hardware. It would completely undermine the entire point of supporting hardware acceleration.

I’m sympathetic to the privacy concerns but this isn’t a solution worth considering.

The solution is to put unncesessary features like WebGL, programmatic Audio API, reading bits from canvas and WebRTC behind a permission.
Who decides what's unnecessary?
Everything that can be used for fingerprinting should be behind a permission. Almost all sites I use (like Google, Hacker News or Youtube) need none of those technologies.
Main thing that ought to be behind a permission is letting Javascript initiate connections or modify anything that might be sent in a request. Should be possible, but ought to require asking first.

If the data can't be exfiltrated, who cares if they can fingerprint?

Letting JS communicate with servers without the user's explicit consent was the original sin of web dev, that ruined everything. Turned it from a user-controlled experience to one giant spyware service.

So CSS should be behind a permission?
No video driver is actually going to implement fixed-time rendering. So you'd have to implement it in user-space, and it would be even slower than WebGL. Nobody wants that. You're basically just saying the feature shouldn't ship in an indirect way (which is a valid opinion you should just express directly.)
I don't mean to prescribe the way to stop fingerprinting, just throwing out a trivial existence proof, and maybe a starting point of thinking, that it's not impossible like was suggested.

Also, WebGPU seems to conceptually support software rendering ("fallback adapter"), where fixed time rendering would seem to be possible even without getting cooperation from HW drivers. Being slower than WebGL might still be an acceptable tradeoff at least if the alternative WebGL API avenue of fingerprinting could be plugged.

Could you explain what techniques would make this possible? I can see how it's possible in principle, if you, say, compile JS down to bytecode and then have the interpreter time the execution of every instruction. I don't immediately see a way to do it that's compatible with any kind of efficient execution model.
The rest would be optimization while keeping the timing sidechannel constraint in mind, hard to say what the performance possibilities are. For example not all computations have externally observable side effects, so those parts could be executed conventionally if the runtime could guarantee it. Or the program-visible clock APIs might be keeping virtual time that makes it seem from timing POV that operations are slower than they are, combined with network API checkpoints that halt execution until virtual time catches up with real time. Etc. Seems like a interesting research area.
>not all computations have externally observable side effects

You can time any computation. So they all have that side effect.

Also, from Javascript you can execute tons of C++ code (e.g. via DOM manipulation). There's no way all of that native code can be guaranteed to run with consistent timing across platforms.

Depends on who you mean by "you". In context of fingerprinting resistance the timing would have to be done by code in certain limited ways using browser APIs or side channels that transmit information outside the JS runtime.

Computations that call into native APIs can be put in the "has observable side effects" category (but in more fine grained treatment, some could have more specific handling).

I'm not sure what you mean. All you need to do is this:

    function computation() { ... }
    before = performance.now();
    computation();
    t = performance.now() - before;
(Obviously there will be noise, and you need to average a bunch of runs to get reliable results.)