Canvas Fingerprinting in the Wild

Every day, your computer renders dozens of these without you even noticing. Strange patterns, colorful shapes, and emojis—what do you think these are?

These are canvas fingerprints, a technique used by the vast majority of websites to fingerprint devices and distinguish humans from bots. What you might not realize is that this is achieved by rendering colorful patterns and emojis, showcasing a surprising layer of creativity from the vendors. In this article, we’ll dive into some unexpected visual artifacts caught in the wild and explore how they contribute to tracking your browser in a truly unique way.

What’s canvas fingerprinting?

Canvas fingerprinting is a technique brought to light in 2012 by 2 researchers from the University of California, San Diego, Keaton Mowery, and Hovav Shacham in their “Pixel Perfect: Fingerprinting Canvas in HTML5” paper. It leverages the Canvas HTML API to draw 2D shapes and text with different sizes and colors. The images drawn are completely invisible to the users since the process happens in the background.

There exist subtle differences in the rendering of the canvas image depending on your browser and your device (OS, GPU, list of fonts installed). Thus, canvas fingerprints are quite unique and stable, which makes it a popular device fingerprinting technique. In 2016, Englehardt et al. showed that canvas fingerprinting was used by 1.6% of the sites in the top Alexa 1M.

Since storing a full image can be costly, most fingerprinting scripts collect a hash of the canvas challenge. Thus, what we call a canvas fingerprint is simply the hash of the image generated by the canvas fingerprinting challenge.

Why does canvas fingerprinting matter for bot detection and to fight fraud?

Properly crafted canvas fingerprints have two main properties that make them useful for detecting bad bots and online fraud:

  1. It tends to be quite unique per user and stable over time. Thus, if used along with other device fingerprinting attributes, it can be used to keep track of malicious users, even if they delete their cookies (in private/incognito mode for example). Moreover, since a canvas fingerprint remains stable for a given user on a given device, this is often used by authentication systems to detect that a user account was compromised. Thus, if they detect a new unknown device fingerprint trying to log into an account, the system can ask for a second authentication factor (SMS, TOTP, email verification code).
  2. The canvas fingerprint value depends on the user's device, OS, and browser. Thus, we can check the canvas fingerprint value against different values of the device fingerprint to check if they’re consistent. For example, we can verify if a canvas fingerprint is consistent with the OS claimed by a user. If that’s not the case, it indicates that the user lied about the nature of his device and may have forged his fingerprints. It can also be used to detect bots running on Linux servers or virtual machines.

Why is there such a diversity of canvas fingerprinting challenges?

Some companies/websites use canvas fingerprinting as a way to build a stable and unique identifier to keep track of a user, in particular fraudsters and bots, even if they delete their cookies. Thus, they want to create a challenge as unique and as stable as possible.

On the contrary, other websites used canvas fingerprinting as a way to infer information about the user device and browser, in particular, to learn about its true nature:

  • Is the browser running on a Linux server?
  • Is it running on a virtual machine?

For example, in 2016, Google researchers proposed Picasso, a dynamic canvas fingerprinting challenge to detect devices spoofing the real nature of their OS or browser. In their paper, they explain how it can be used to detect desktop devices pretending to be iPhones or to distinguish between real Android devices and Android emulators.

In the image below, from their paper, they show the difference between a Picasso canvas fingerprint coming from a real Chrome browser vs other browsers. Thus, because a given canvas fingerprint challenge is stable on a given browser/OS, they can detect whenever someone is lying about the real OS of his device.

You may be wondering why so many canvas fingerprinting challenges use emojis. As shown by Laperdrix et al. in their "Beauty and the Beast: Diverting modern web browsers to build unique browser fingerprints” paper, canvas fingerprints leverage emojis since their rendering depends on the OS or even the type of phone, cf image below.

Thus, it can be used to detect users that lie about the true nature of their device, but also to make the canvas more unique as it incorporates more information about the user's device.

Example code

The code below illustrates how to collect a canvas fingerprint. The value of the canvas fingerprinting challenge is stored in the canvasFingerprint variable thanks to the toDataURL function.

const canvas = document.createElement('canvas');
canvas.width = 400;
canvas.height = 200;
const context = canvas.getContext("2d");

context.rect(0, 0, 10, 10);
context.rect(2, 2, 6, 6);

context.textBaseline = "alphabetic";
context.fillStyle = "#f60";
context.fillRect(125, 1, 62, 20);
context.fillStyle = "#069";
context.font = "11pt no-real-font-123";
context.fillText("Cwm fjordbank glyphs vext quiz, 😃", 2, 15);
context.fillStyle = "rgba(102, 204, 0, 0.2)";
context.font = "18pt Arial";
context.fillText("Cwm fjordbank glyphs vext quiz, 😃", 4, 45);

context.globalCompositeOperation = "multiply";
context.fillStyle = "rgb(255,0,255)";
context.beginPath();
context.arc(50, 50, 50, 0, 2 * Math.PI, !0);
context.closePath();
context.fill();
context.fillStyle = "rgb(0,255,255)";
context.beginPath();
context.arc(100, 50, 50, 0, 2 * Math.PI, !0);
context.closePath();
context.fill();
context.fillStyle = "rgb(255,255,0)";
context.beginPath();
context.arc(75, 100, 50, 0, 2 * Math.PI, !0);
context.closePath();
context.fill();
context.fillStyle = "rgb(255,0,255)";
context.arc(75, 75, 75, 0, 2 * Math.PI, !0);
context.arc(75, 75, 25, 0, 2 * Math.PI, !0);
context.fill("evenodd");
const canvasFingerprint = canvas.toDataURL();

On a Chrome browser version 131 running on MacOS, the canvas fingerprint looks as follows:

Similar types of fingerprinting

Similarly to canvas fingerprinting, WebGL fingerprinting leverages the WebGL API to draw a 3D image whose value also depends on the user device. The image below shows the output of a WebGL fingerprinting challenge.

Besides drawing images, other device fingerprinting challenges leverage the web audio API to detect the subtle differences in how a device renders audio content.

WebGPU and the future of fingerprinting

The WebGPU API is the successor of the WebGL API. It can be used from JS to leverage the underlying device GPU to run high-performance computations and draw complex images that can be rendered in the browser. While it is already used to obtain fingerprinting information such as the GPU architecture and vendor using the GPUAdapter API, it will probably be a future companion of canvas, webGL, and audio fingerprinting challenges to better determine the true nature of the user device, even when fraudsters and bots apply heavy modifications to their device fingerprint!