PowerScan

PowerScan Blog

Canvas fingerprinting explained: why two identical browsers draw different pixels

· 6 min read

Canvas fingerprinting is the technique most people have heard of and fewest can explain. The idea is simple: ask the browser to draw something, read the pixels back, and hash them. The interesting part is why the pixels differ between machines at all.

The drawing

A fingerprinting script creates an off-screen <canvas>, gets a 2D context, and draws a short sequence: a filled rectangle, some text in a named font, maybe a gradient, a curve, an emoji. Then it calls toDataURL() or getImageData() to read the result, and runs the bytes through a hash. The output is a short string such as 71ae464e. That string is the "canvas hash".

Nothing about the drawing is secret, and nothing is sent to the GPU that the page could not already describe. The information is in the rendering, not the instructions.

Why the pixels differ

Text is the main source of variation. Rendering a glyph involves the font file that was actually chosen (fallbacks differ by operating system), the hinting and anti-aliasing strategy (greyscale or sub-pixel, and which sub-pixel order), the rasteriser (FreeType, DirectWrite, CoreText, or a browser's own), and whether the GPU or the CPU did the compositing. Each of these produces slightly different edge pixels. A single light-grey pixel at the edge of an "e" is enough to change the hash completely.

Gradients and curves add more: different graphics drivers and different anti-aliasing paths round intermediate values differently. The result is that two machines with the same browser version but different GPUs, drivers or operating systems will usually produce different hashes, while the same machine produces the same hash every time. Stable and diverse, which is exactly what a tracker wants.

What a hash tells a site

By itself, nothing about who you are. It tells the site that this browser renders this drawing this way, which is true of some group of machines. The size of that group is what matters. A common laptop with integrated graphics and default fonts shares its hash with many others. An unusual setup can be close to unique. Combined with a screen size, language list and renderer string, even a common hash becomes part of a rare combination.

What browsers do about it

Firefox, with resist-fingerprinting enabled, returns a blank or randomised canvas and can prompt for canvas access. Brave adds small random perturbations to canvas reads so the hash changes between sites and sessions. Safari limits which fonts are visible and constrains some readbacks. Chromium itself does not randomise canvas; browsers built on it that aim to control fingerprints do so with their own patches, and the quality of those patches varies.

Noise is not free. A canvas hash that changes every visit is itself a signal, because real browsers do not do that. The better strategy for an isolated browser profile is a hash that is plausible and consistent, so it looks like one ordinary machine rather than a different machine every hour.

What a diagnostic shows

PowerScan draws its own small image and shows you the hash. It never uploads it; the value exists only in your tab. Reload and the hash should be identical. If it is not, something in the browser is injecting noise, which is worth knowing before you rely on that profile.

All articles · Run the scan