EFForg / privacybadger

Privacy Badger is a browser extension that automatically learns to block invisible trackers.
https://privacybadger.org
Other
3.19k stars 386 forks source link

Privacy Badger triggers API tampering detection tests intended for CanvasBlocker #2497

Open siebenbrodt opened 5 years ago

siebenbrodt commented 5 years ago

Privacy Badger 2019.10.28, Firefox 70.0.1 on Windows 8.1 Privacy Badger 2019.10.28, Firefox 70.0 on Fedora Linux 31 Freshly made profile, no other extensions installed.

Enabling or disabling Firefox's native Enhanced Tracking Protection, Privacy Badger's Send websites the "Do Not Track" signal, Prevent WebRTC from leaking local IP address or Enable widget replacement does not affect the result.

https://canvasblocker.kkapsner.de/test/detectionTest.html – "API tampering detected". Each test code pops up when you hover over its name. http://f.vision/ – "Detected fake canvas. Some tests shows that your canvas change default browser functionality of getImageData method". Screenshot from 2019-11-05 01-00-04

ghostwords commented 5 years ago

Hello and thanks for getting in touch!

What this means is that websites can tell that something tampered with certain canvas-related JavaScript methods (as well navigator.doNotTrack). Privacy Badger modifies JavaScript methods to detect when a script performs canvas fingerprinting (and to send the Do Not Track signal via JavaScript).

Ideally, we'd be able to intercept various JS calls and set navigator.doNotTrack in a way that does not unintentionally affect anything about the JavaScript environment.

According to https://github.com/kkapsner/CanvasBlocker/issues/145#issuecomment-342521269, CanvasBlocker relies on exportFunction(), a Firefox-specific way for content scripts to inject JS into webpages. @kkapsner Is this how you are able to preserve original .toString(), .length, etc. values? Are ES6 Proxies/Reflect not enough for your purposes?

Ultimately though, any extension that modifies anything on the Web is inherently detectable. This doesn't mean we shouldn't try to be less conspicuous, or to break fewer sites. For example, a different JS interception technique might resolve outstanding fingerprinting-detection-adjacent bugs such as #1854.

siebenbrodt commented 5 years ago

Hello and first of all, thank you and your team for keeping up the good work!

I understand that every bit on the Web is counted, but to clarify the context of my concern: to my considerable surprise, I found that this detector reacts only to PB and stays completely indifferent even when my entire paranoid extension zoo is turned on (and Firefox Protection too!) Maybe the methods of these extensions can also lead to any thoughts. As for DNT, I never use it in any form.

Detection-test-all-extensions-Firefox-70 0 1-on-Windows-8 1

ghostwords commented 5 years ago

Privacy Badger is the only one that automatically discovers trackers as you browse. As I wrote above, Privacy Badger modifies JavaScript methods to detect when a script performs canvas fingerprinting, and also to send the Do Not Track signal (enabled by default) via JavaScript.

kkapsner commented 5 years ago

Yes, exportFunction helps to preserve these values (you have to be carefully with getters and setters). But the main benefit is that your injected functions can use the webExtension APIs and can directly communicate with the rest of your code.

I do not see how Reflect could help in this scenario and Proxies are very easy to detect (via instanceof).

ghostwords commented 5 years ago

OK, thank you! I suppose we could improve injection in Firefox anyway.

you have to be carefully with getters and setters

Could you explain a bit more? Perhaps you could point to relevant code or commits in CanvasBlocker. Thanks again for chiming in!

ghostwords commented 5 years ago

Here is an interesting proposal for the ability to hide implementation details: https://github.com/tc39/proposal-function-implementation-hiding

Another unnecessary insight gained by f.toString() is how a function was created. Most dramatically, it can be used to detect whether an implementation is "native" or not, by looking for the pattern of [native code].

kkapsner commented 5 years ago

For the getters and setters to look properly the functions actually have to be defined as such: https://github.com/kkapsner/CanvasBlocker/blob/master/lib/modifiedHistoryAPI.js#L22