Canvas is the HTML element pages use to draw graphics. A fingerprinting script uses it in a way no visitor sees: it draws a short string in a few fonts, some overlapping shapes and color gradients into a canvas, then asks for the pixels back with toDataURL() or getImageData() and hashes them.
Why the result differs between machines
The drawing instructions are identical everywhere. The pixels are not. Text antialiasing, subpixel positioning, font hinting, the GPU and its driver, and the operating system's graphics stack all leave small differences in the output. Two computers with different hardware or fonts usually produce different hashes; two identical ones may match. So a canvas hash is not unique on its own, but it adds a lot to a browser fingerprint and it survives clearing cookies.
The same idea is used with WebGL, which renders a 3D scene and reads it back, and with text measurement, where the width of a string reveals the fonts installed.
Every profile is drawn from one real computer, not from separate listsIn Mosaic: Machines that exist. GPU, screen, CPU and fonts from one real device. Free holds 3 profiles. Pro is $49 a month for any number.
Mosaic is a desktop app
Email yourself the link and open it on your computer.
How it works: Machines that exist
How it is defended against, and how that shows
There are three common defenses, and each leaves a mark.
- Blocking the readback. Rare in real traffic, so the refusal is itself distinctive.
- Random noise on every read. The hash changes each time, which a page detects by drawing the same thing twice and comparing. No real machine does that.
- Noise that is stable per profile. The same drawing reads back the same way every time inside one profile, and differently in another. This is the shape a real computer has.
Where the noise is added matters too. A script injected into the page that wraps toDataURL() can be caught wrapping it, and misses readbacks a page does in a worker or through a blob.
How Mosaic handles it
Mosaic adds canvas noise inside its own engine, in C++, at the point where image data is read back, including toBlob() and WebGL's readPixels(). The noise belongs to the profile, so a profile keeps its canvas identity across launches, and repairing a profile's hardware keeps it too. Machines that exist covers how the rest of the profile is drawn, and why we built our own Chromium explains why none of it is done with injected JavaScript.





