brave / brave-browser

Brave browser for Android, iOS, Linux, macOS, Windows.
https://brave.com
Mozilla Public License 2.0
18k stars 2.36k forks source link

Canvas Anti-Fingerprinting causes websites to break and can't be turned off #10000

Closed rebane2001 closed 4 years ago

rebane2001 commented 4 years ago

Description

Brave Canvas Anti-Fingerprinting causes websites to break if the website requires pixel-perfect color output, because Brave adds random noise to canvases when using the getImageData method. This CAN NOT be turned off even with shields down.

Steps to Reproduce

  1. Turn off shields
  2. (optional) Turn off all other tracking protection
  3. Press F12, open up the Console and run the following code:
    // Create HTML5 canvas
    let canvas = document.createElement('canvas');
    canvas.width = 1024;
    canvas.height = 1024;
    let ctx = canvas.getContext('2d');
    // Set the color to pure white and draw a rectangle filling the entire canvas
    ctx.fillStyle = "rgba(255, 255, 255, 1)";
    ctx.fillRect(0, 0, 1024, 1024);
    // Get the image data from the canvas
    let imageData = ctx.getImageData(0, 0, 1024, 1024);
    // Go through every RGBA value of every pixel and log "oh no" if it is not pure white
    imageData.data.forEach(e => {if(e != 255) console.log("oh no")});

Actual result:

The words "oh no" appear in the console, meaning that the pixel color is incorrect.

Expected result:

The words "oh no" DO NOT appear in the console.

Reproduces how often:

Easily reproduced

Brave version (brave://version info)

Brave 1.9.72 Chromium: 81.0.4044.138 (Official Build) (64-bit) Revision 8c6c7ba89cc9453625af54f11fd83179e23450fa-refs/branch-heads/4044@{#999} OS Windows 10 OS Version 1809 (Build 17763.1217) JavaScript V8 8.1.307.32

Version/Channel Information:

Other Additional Information:

Miscellaneous Information:

In case you are wondering where this type of bug can break sites in practice, I run an open-source website called MapartCraft, which lets players convert images into art they can use in the game Minecraft. Since it chooses the blocks to place by comparing the colors on the canvas to the colors of the blocks in-game, having the canvas color values be off even by one causes the entire site to break.

bsclifton commented 4 years ago

cc: @pes10k

pes10k commented 4 years ago

The ability to turn this protection off is in https://github.com/brave/brave-browser/issues/9194

Would be a good candidate to uplift when its closed (should be very soon)

pes10k commented 4 years ago

This is fixed as of 1.11 (you can disable farbling fingerprinting using shields in nightly on). Closing :)

pes10k commented 4 years ago

Adding QA/Yes. A sufficient test would be to just set the default fingerprinting protection to max / strict, and then verify that you can successfully set it to both lower levels on a per-site basis.

LaurenWags commented 4 years ago

Verified passed with

Brave | 1.11.85 Chromium: 83.0.4103.116 (Official Build) dev (64-bit)
-- | --
Revision | 8f0c18b4dca9b6699eb629be0f51810c24fb6428-refs/branch-heads/4103@{#716}
OS | macOS Version 10.14.6 (Build 18G3020)

Verified passed with

Brave   1.11.87 Chromium: 83.0.4103.116 (Official Build) dev (64-bit)
Revision    8f0c18b4dca9b6699eb629be0f51810c24fb6428-refs/branch-heads/4103@{#716}
OS  Linux

Verification passed on


Brave | 1.11.90 Chromium: 83.0.4103.116 (Official Build) dev (64-bit)
-- | --
Revision | 8f0c18b4dca9b6699eb629be0f51810c24fb6428-refs/branch-heads/4103@{#716}
OS | Windows 10 OS Version 1903 (Build 18362.900)
jez9999 commented 1 year ago

Ugh, this is horrible. The "anti-fingerprinting" cure is far worse than the problem. It is going to break anything that relies on precise pixel values for canvas. For example, the Konva framework completely relies on this for hit detection. You've broken Konva, by default.

qiu-x commented 1 year ago

Ugh, this is horrible

On the contrary, this is great and every browser should implement this. Firefox has already WIP canvas salting support and more browsers will follow.

precise pixel values for canvas

If the values were so precise in the beginning, it wouldn't be possible to fingerprint users based on small differences (like anti-aliasing or font hinting) in the canvas rendering implementation.

Konva framework completely relies on this for hit detection

And that in your opinion is more important than the privacy of everyone browsing the web? Ad vendors were also unhappy when the deprecation of third-party cookies was announced, but the Web is a dynamic place and things change. If this is so bad in your opinion, perhaps you could suggest a better approach to solve this issue?

jez9999 commented 1 year ago

TBH I don't really understand how this is even an "issue". I tried to Google it but didn't come up with much. Why does accurate reporting of canvas values allow anyone to really track you accurately, or know any detailed information about you?

qiu-x commented 1 year ago

If you make a enough complicated canvas it basically allows you to uniquely identify a driver+gpu combination used by someone visiting your website. Here is a example canvas I rendered on two different machines:

let canv = document.createElement("canvas");
canv.width = 200;
canv.height = 70;
let ctx = canv.getContext("2d");
ctx.fillStyle = "rgba(255,150,150, 0.6)";
ctx.font = "15pt Arial";
ctx.textBaseline = "top";
ctx.fillText("Hello There!", 2, 2);
ctx.fillStyle = "#00FF00";
ctx.fillRect(50, 5, 35, 15);
ctx.fillStyle = "#FF4353";
ctx.fillRect(70, 15, 30, 25);

And here is a image diff between them I made using ImageMagick: diff (of course this canvas algorithm is just an example and not really suited for fingerprinting)

If you convert that canvas into a hash, you get a compact identifier of that particular hw+driver configuration. The canvas even differs when you use the same gpu but different drivers i.e. Mesa vs a Windows driver. Since the canvas is usually hashed, small changes to the canvas are sufficient enough to break the fingerprinting mechanism - this is what Brave does.

https://en.wikipedia.org/wiki/Canvas_fingerprinting

jez9999 commented 1 year ago

What's the problem with them knowing your driver+gpu?

qiu-x commented 1 year ago

What's the problem with them knowing your driver+gpu?

Combined with other fingerprinting techniques it gives you the ability to uniquely identify devices. You're essentially asking "Why is the tracking of end-users bad?". Well of course not everybody cares about privacy, but that doesn't mean that we shouldn't make it possible to privately browse the Web at all. As a matter of fact, tracking can be used for malicious reasons, like for identifying activists in countries with unethical regimes/dictatorships, etc. And if a particular API allows for such tracking, that means that it's broken and a fix like this one is needed. And if you need precise pixel values, you can always make the bitmap yourself without relying on the canvas API. I mean if it doesn't fit your assumptions why depend on it?

jez9999 commented 1 year ago

I'm not the one who wrote the Konva framework. Presumably, rendering 2 canvases and checking the pixel values to determine a shape hit on a shadow canvas is a nice convenient way of detecting shapes compared to manually calculating their dimensions, because the browser's likely to render the shadow canvas's shape in the same kind of antialiased way that it does for the main canvas's shape. It's rather a shame if that technique won't work anymore.

pes10k commented 1 year ago

just a note that for sites that need precise pixel values for benign, user serving purposes, they can still get them by detecting brave (navigator.brave === true), and explaining to the user why they should drop shields for the site, or disable fingerprinting protections for the site.

jez9999 commented 1 year ago

just a note that for sites that need precise pixel values for benign, user serving purposes, they can still get them by detecting brave (navigator.brave === true), and explaining to the user why they should drop shields for the site, or disable fingerprinting protections for the site.

Well yeah. But it rather sucks because we're back to the days of what it was like with Flash game plugins. The idea was that with HTML5/JS, people could just load up the site and stuff would work, whereas with Flash you'd have to explicitly allow the plugin (download it sometimes), and users would often worry about its being insecure. They'd be less likely to use the site.

If people (and not just in Brave, but you're hoping all the basic browsers too like Firefox and Chrome) have to start doing something that is characterized as "allow site to access potentially dangerous canvas information", fewer people are likely to use the site, based on this (IMHO) rather theoretical problem of a vague fingerprinting technique which lets companies track which websites you're visiting (only when combined with other techniques).

I think that is a shame, frankly, and I think users would usually be right to turn the protection off, which makes it a questionable measure in the first place. As for alternative techniques for hit detection, there aren't any really for complex shapes. Except for one thing you said earlier: you could manually render each pixel yourself. Yeah you could do that, re-invent the wheel and lose all the benefits of the canvas API except this time much slower, because of no hardware support. What an awful solution.