Canvas fingerprint noise backfires unless done carefully. Learn why naive randomization is detectable and how Brave's farbling avoids the trap.
Canvas noise — the practice of injecting small random differences into the pixel data your browser returns when a tracking script reads the canvas — sounds like an elegant fix. Change the hash each time, and a tracker can never pin a stable identifier to your device. In practice the story is more complicated: poorly designed noise is detectable in two API calls, and detecting it is enough to classify you as a privacy-tool user. This article unpacks how noise works, why randomization can backfire, what separates structured noise from naive randomness, and how Brave's farbling avoids most of the pitfalls — while still leaving some footprint of its own.
Key Takeaways
- Canvas noise aims to break stable fingerprinting by randomizing the pixels a tracking script reads back.
- Naive randomization is detectable in two API reads: if the same canvas returns different pixels each call, something is modifying the output.
- Structured, per-session, per-origin noise (like Brave's farbling) avoids that tell but still signals that protection is active.
- Uniformity — making your canvas output match a large crowd — is more robust than randomization for the strongest anonymity.
- Noise magnitude matters: large noise is statistically obvious; small noise can be averaged out over repeated samples.
How Canvas Noise Works
A canvas fingerprinting script draws a fixed scene and reads back the pixels via toDataURL() or getImageData(). Those pixels encode your GPU, font engine, and graphics driver — hardware properties that stay fixed across page loads. Canvas noise tools intercept the readback and alter the returned data before it reaches the script.
There are two broad approaches to altering it:
Blocking or blanking. Return an empty canvas, an all-white result, or throw an error. This stops fingerprinting completely but is immediately obvious: a blank result is itself a fingerprint — every visitor using this setting looks identical. A single data.every(b => b === 0) check detects it.
Noise injection. Keep the real pixels but perturb them slightly — adding ±1 or ±2 to random RGB channels — so the hash changes while the visual appearance remains plausible. Most privacy extensions (CanvasBlocker, JShelter) and Brave's farbling use a variant of this approach.
The critical design question is: how is the noise seeded? The seeding strategy determines whether the noise is detectable and whether it can be reversed.
Why Naive Randomization Is Detectable
Suppose a noise tool generates a fresh random seed on every API call. Call getImageData() twice on the same unchanged canvas, and you get two different byte arrays. That should never happen in a real browser — a canvas is a bitmap, and reading it twice without any drawing in between yields identical results. A fingerprinting script that calls the API twice and compares the outputs immediately concludes: noise is present.
This is not a theoretical attack. Canvas fingerprinting libraries check for it because it reliably distinguishes modified from unmodified readbacks. Even if the script cannot recover the real hash, it now knows you are running canvas protection — and that knowledge is itself a signal. In some classification systems, "confirmed privacy-tool user" is a more valuable identifier than a stable hash, because it corresponds to a specific, smaller population.
Beyond the double-read test, naive randomization has a second weakness: the distribution of the noise is itself a fingerprint of the tool. If your noise is uniformly ±1 per channel with a specific seeding algorithm, the statistical properties of the returned pixels — mean offset, variance, channel correlation — identify the exact extension and version. Two users running the same CanvasBlocker build with identical settings produce noise components that are statistically similar, making them distinguishable from genuine GPU variation even across different underlying hardware.
Structured Noise: The Smarter Alternative
Structured noise replaces per-call randomness with a deterministic seed that satisfies three properties:
- Consistent within a session. Two reads of the same canvas during the same browser session return the same noisy bytes. The double-read test passes.
- Unique per origin. The noise applied on
bank.comdiffers from the noise onshop.com, so a third-party tracker embedded on both cannot correlate canvas hashes across those sites. - Unpredictable across sessions. A new browser session uses a new seed, breaking cross-session tracking.
With this design, the double-read detection fails. The noise is stable and internally consistent, so it is far harder to distinguish from genuine GPU-level variation. Cross-site and cross-session linking are both severed.
The cost is that structured noise still signals that something is modifying canvas output. An adversary comparing many users' pixel arrays against a reference can detect statistical regularities corresponding to small deterministic offsets — but doing this requires a known reference for each victim's exact hardware configuration, which a remote server does not have.
Brave's Farbling: How It Works
Brave's farbling is a production implementation of structured noise, built directly into the browser rather than delivered as a userspace extension. That placement matters: because it operates below the JavaScript layer, no script can distinguish farbled readbacks from genuine browser behavior by inspecting prototype chains or timing the API.
The seeding design implements all three structured-noise properties:
- Installation secret. A random seed is generated at install time and stored securely in the browser profile. It does not change unless the profile is reset.
- Per-origin derivation. The installation secret is combined with a hash of the current site's eTLD+1, producing a different noise profile for each website. A tracker on
adnetwork.comsees a different canvas hash than the same tracker onnews.com, even though the underlying hardware is unchanged. - Per-session nonce. A fresh random value mixed in at session start rotates the profile on every browser restart, preventing cross-session correlation.
The pixel perturbation is small — typically ±1 on randomly selected color channels — keeping the visual output indistinguishable from unmodified rendering. Brave applies farbling to WebGL, audio, and several other fingerprinting surfaces alongside canvas, so the noise does not stand out against an otherwise normal-looking signal set.
Can Farbling Be Reversed?
Recovering the original canvas hash requires knowing the expected pixel values from the victim's exact GPU, driver, and font stack. A remote server cannot generate that reference without physical access to the same hardware. Averaging across sessions also fails: the per-session nonce ensures that repeated visits produce different offsets, so the mean of two farbled readings is not closer to the true hash than either reading alone.
Farbling is not undetectable at the population level, however. Research on large fingerprint corpora has shown that Brave users' canvas outputs cluster differently from stock Chromium outputs — the perturbation pattern is a mild but real indicator that Brave is the browser in use. You remain identifiable as a Brave user, a population of tens of millions rather than billions, but individual-level tracking is effectively broken. EFF's Cover Your Tracks is a public tool for seeing what trackers actually observe from your browser, including whether your canvas output appears stable or randomized.
Uniformity vs. Randomization: The Deeper Trade-Off
Brave's farbling is among the best noise implementations available, but it highlights a structural tension in fingerprint defenses: randomization limits what a tracker can do with your fingerprint, while uniformity removes the fingerprint as a signal entirely.
Tor Browser defends canvas differently. It returns a standardized, near-blank value for every user so that all Tor users appear identical to a tracker. There is no noise, no hash variation, no statistical signature — only the absence of a meaningful canvas readback. A tracker learns nothing about your rendering pipeline, and you blend into the Tor anonymity set. The trade-off is a more constrained browsing experience and the clear signal that you are running Tor.
For users who want to break everyday cross-site ad tracking while maintaining normal browsing, farbling achieves that goal well. For users who need to be undetectable in high-stakes scenarios, uniformity is the stronger posture. Combining both — applying farbling within a Tor session — can actually be counterproductive, because it breaks the uniformity that Tor's defense depends on.
The full picture of how canvas combines with WebGL, audio, and other signals into a composite fingerprint appears in our canvas fingerprint detection guide and browser fingerprinting explained.
Frequently Asked Questions
Can a tracking script reverse the noise and recover my real canvas hash?
In practice, no. Recovering the true hash requires a reference rendering from the victim's exact hardware stack — GPU model, driver version, OS font engine, and browser version. A remote server cannot generate that reference. Averaging across sessions also fails with Brave's farbling because the per-session nonce changes the offset on every restart.
Does canvas noise protect against all fingerprinting?
No. Canvas is one signal among many. Even if canvas noise breaks the canvas hash, your WebGL renderer string, font list, screen resolution, and audio fingerprint remain unchanged. A tracker with access to those other signals can often still narrow down your anonymity set substantially.
Is CanvasBlocker as good as Brave's farbling?
Both can use structured noise, but Brave's implementation is harder to detect and bypass: it operates below the JavaScript API layer, so a script cannot distinguish it from genuine browser behavior by examining the prototype chain. A userspace extension patches the JavaScript prototype at a level that sophisticated scripts can probe. CanvasBlocker with structured noise enabled is substantially better than naive per-call randomization or blanking, but it is not equivalent to browser-level protection.
How do I check whether my canvas output looks noisy or stable?
Run BrowserInsight's fingerprint check. It computes your live canvas hash, shows whether the value appears stable, and estimates how unique your overall fingerprint is relative to common configurations.


