Guide11 min read

Canvas and WebGL Fingerprinting

Short answer

A canvas fingerprint is a short hash of an image your browser draws on a hidden HTML5 <canvas>: a script renders text, emoji and shapes, reads the pixels back and hashes them, and because fonts, graphics drivers and GPUs render a little differently, the hash differs from one device to another while staying the same on yours. A WebGL fingerprint does the same with 3D graphics and also reads your graphics card's name. Neither depends on your IP address, so a proxy does not change them; ProxyField's 412M+ residential IPs change the address a site sees, and you can start with the Easy Trial: 1 GB for $2.95.

residential IPs
412M+
from, traffic never expires
$1.95/GB
Easy Trial
1 GB for $2.95
On this page 10 sections
  1. What is a canvas fingerprint?
  2. How canvas fingerprinting works, step by step
  3. What is WebGL fingerprinting?
  4. How common is it?
  5. Test your canvas and WebGL fingerprint
  6. Canvas and WebGL in web scraping
  7. How to block or change canvas and WebGL fingerprints
  8. What a proxy changes, and what it does not
  9. Sources
  10. Canvas and WebGL Fingerprinting FAQ

What is a canvas fingerprint?

A canvas fingerprint is one value in a browser fingerprint: the hash of a test image that a website asks your browser to draw. The technique was first described in 2012 by Keaton Mowery and Hovav Shacham of UC San Diego, who rendered text and WebGL scenes to a <canvas> element and examined the pixels produced. They called the result "consistent, high-entropy, orthogonal to other fingerprints, transparent to the user, and readily obtainable": in 294 tests on Amazon's Mechanical Turk they saw 116 different values (Pixel Perfect: Fingerprinting Canvas in HTML5, W2SP 2012).

Two properties make it useful to trackers and to bot detection:

  • It is stable. The same browser on the same machine draws the same pixels every time, so the hash survives cleared cookies and private windows.
  • It varies between setups. The operating system's font rendering, the graphics driver, the GPU and the browser version all leave traces in the pixels.

A canvas hash alone rarely identifies one person, because many people share the same laptop model and browser. It narrows the crowd, and combined with the other signals in a fingerprint (screen, fonts, time zone, language, user agent) it can single out a device. The full set of signals is in what is a browser fingerprint.

How canvas fingerprinting works, step by step

  1. Draw

    A script creates a <canvas> element, often invisible or off-screen, and draws a fixed scene: a sentence in a chosen font, an emoji, overlapping colored shapes with transparency, sometimes a gradient.

  2. Read the pixels back

    It calls toDataURL(), which returns "a data URL containing a representation of the image" (MDN: toDataURL), or getImageData(), which returns the raw pixel values.

  3. Hash

    It turns that long string or byte array into a short hash, such as a 32-bit integer or a SHA-256 digest. The hash is what gets stored and compared; the image itself is thrown away.

  4. Compare

    The site compares the hash with what it saw before for this visitor and with what it expects from the browser and system the visitor claims to be.

Why the pixels differ is the interesting part: text anti-aliasing and subpixel rendering differ between Windows, macOS and Linux, emoji come from different font files, and blending semi-transparent colors goes through the graphics stack. A change of browser version or graphics driver can change the hash; a change of IP address cannot.

What is WebGL fingerprinting?

WebGL fingerprinting uses the browser's 3D graphics API, WebGL, to read details of your graphics hardware. It collects two kinds of data:

What it readsHowExample
Renderer and vendor stringsThe WEBGL_debug_renderer_info extension exposes UNMASKED_VENDOR_WEBGL and UNMASKED_RENDERER_WEBGLOn a desktop, a string that names the GPU and the graphics API; on a server without a GPU, a software renderer (see the test below)
CapabilitiesgetParameter() and getSupportedExtensions(): maximum texture size, shader precision, the list of supported extensionsA long list that differs by GPU, driver and browser
A rendered sceneDraw a 3D shape with lighting and textures, read the pixels back and hash them, as in canvas fingerprintingA hash that changes with the GPU and driver

MDN describes the debug extension as exposing "two constants with information about the graphics driver for debugging purposes", and notes that depending on the browser's privacy settings it may be unavailable; in Firefox with privacy.resistFingerprinting set to true it is disabled (MDN: WEBGL_debug_renderer_info).

Related techniques work the same way with other APIs. Audio fingerprinting processes a generated sound through the Web Audio API (OfflineAudioContext) and hashes the output; Englehardt and Narayanan's 1-million-site study was the first to measure it at scale, and font fingerprinting uses the canvas to measure which fonts are installed (Online Tracking: A 1-million-site Measurement and Analysis, 2016).

Easy Trial: 1 GB for $2.95.
Try for the price of 1 GB, no subscription, traffic never expires.

How common is it?

Common enough that you meet it daily, on a minority of sites. A 2014 crawl of the 100,000 most popular sites found that more than 5.5% ran canvas fingerprinting scripts on their home pages, 95% of them from a single provider (Acar et al., The Web Never Forgets, ACM CCS 2014). The 2016 study above found canvas fingerprinting on 14,371 of 1 million sites (1.6%), 98.2% of it from third-party scripts, and more often on popular sites: 5.10% of the top 1,000. Since then, canvas and WebGL values have also become inputs to fraud-prevention and anti-bot scripts, which read them to check that a browser is what it claims to be (see the scraping section below).

Test your canvas and WebGL fingerprint

You can see your own values in about a minute.

Online tests:

  • BrowserLeaks: Canvas shows your canvas signature, how unique it is in the site's own sample, and the image details; it also has a WebGL page.
  • EFF: Cover Your Tracks shows how identifiable your whole fingerprint is, canvas and WebGL included.
  • CreepJS is an open-source test that also looks for signs that values were faked.
  • AmIUnique compares your fingerprint with its collected sample.

Your own check, in the browser console (on any HTTPS page, F12, Console):

JavaScript
async function canvasHash() {
  const c = document.createElement('canvas');
  c.width = 280; c.height = 60;
  const ctx = c.getContext('2d');
  ctx.textBaseline = 'top';
  ctx.font = '16px Arial';
  ctx.fillStyle = '#f60';
  ctx.fillRect(100, 1, 62, 20);
  ctx.fillStyle = '#069';
  ctx.fillText('Cwm fjordbank glyphs vext quiz \u{1F603}', 2, 15);
  ctx.fillStyle = 'rgba(102, 204, 0, 0.7)';
  ctx.fillText('Cwm fjordbank glyphs vext quiz \u{1F603}', 4, 17);
  const bytes = new TextEncoder().encode(c.toDataURL());
  const digest = await crypto.subtle.digest('SHA-256', bytes);
  return [...new Uint8Array(digest)].map(b => b.toString(16).padStart(2, '0')).join('').slice(0, 16);
}

function webglInfo() {
  const gl = document.createElement('canvas').getContext('webgl');
  if (!gl) return 'WebGL unavailable';
  const ext = gl.getExtension('WEBGL_debug_renderer_info');
  return ext
    ? `${gl.getParameter(ext.UNMASKED_VENDOR_WEBGL)} | ${gl.getParameter(ext.UNMASKED_RENDERER_WEBGL)}`
    : `${gl.getParameter(gl.VENDOR)} | ${gl.getParameter(gl.RENDERER)}`;
}

canvasHash().then(h => console.log('canvas:', h, '| webgl:', webglInfo()));

Run it twice, then in a private window, then through a proxy: the canvas hash stays the same each time, because none of those change how your machine draws. Run it in another browser on the same computer and it usually changes. We ran this snippet twice in headless Chromium 156 on a Linux server with no graphics card: both runs gave the same hash, and WebGL reported "ANGLE (Google, Vulkan 1.3.0 (SwiftShader Device (Subzero) ...), SwiftShader driver)", a software renderer that no ordinary home computer reports.

Canvas and WebGL in web scraping

For scrapers, canvas and WebGL are less about tracking and more about consistency. Anti-bot scripts read them to check whether the browser is what it says it is:

  • Software renderers. Headless browsers on servers without a GPU report SwiftShader or llvmpipe as the WebGL renderer, as our test shows. A visitor claiming to be Chrome on Windows with a SwiftShader renderer is an easy flag. What else gives automated browsers away: browser fingerprinting and scraping.
  • Contradictions. A macOS user agent with a canvas hash that only Linux font rendering produces, or a WebGL renderer that names a GPU the claimed device never shipped with.
  • Unstable values. Randomizing tools add noise to the canvas output. If the same scene drawn twice on one page gives two different hashes, the noise itself becomes the signal.
  • Too many visitors with one hash. A thousand "different" visitors on a thousand IPs who all share one rare canvas hash look like one machine.

Rotating residential IPs solve a different problem: they spread requests over many addresses so that no single IP crosses a rate limit or carries a datacenter label. Fingerprints and IPs have to agree with each other, so pair the IPs with browser profiles that look like real, common devices; antidetect browsers manage canvas and WebGL values per profile (antidetect browser proxies).

How to block or change canvas and WebGL fingerprints

Browsers handle it in three ways, each with trade-offs:

ApproachExampleTrade-off
BlockFirefox with privacy.resistFingerprinting disables the WebGL debug extensionSites that need canvas or WebGL can break; blocking is itself rare and visible
Randomize ("farbling")Brave randomizes "fingerprintable values in ways that are imperceptible to humans", so the browser looks different "both between websites and between browsing sessions" (Brave: Fingerprint randomization, 2020)Defeats tracking across sites; noise can be detected as noise
Add noise, limit known scriptsSafari 17 added "noise to fingerprintable web APIs" in Private Browsing (WebKit: Safari 17.0, 2023); Safari 26 "prevents known fingerprinting scripts from reliably accessing web APIs that may reveal device characteristics", 2D canvas included, in all browsing (WebKit: Safari 26, 2025)Works against scripts Safari knows; a new or unlisted script still reads the values

For privacy, randomization defeats tracking across sites. For scraping, it is the wrong goal: a randomized fingerprint is unusual by design, while a scraper wants to look like the most common real device of its claimed type. That means a full browser on real or well-emulated hardware, consistent values across a session, and the same profile on the same sticky IP. How spoofing tools work and how sites catch them: fingerprint spoofing.

What a proxy changes, and what it does not

SignalChanged by a proxy?
IP address, its network type and countryYes
Canvas hashNo
WebGL renderer and rendered-scene hashNo
Audio and font fingerprintsNo
Time zone and language reported by the browserNo; set them to match the proxy's location yourself
TLS handshakeNo; it is your client's (TLS and TCP fingerprinting)

So a proxy and a fingerprint do different jobs. ProxyField gives you 412M+ residential IPs in 195+ countries, with targeting by country, region (state) and city, per-request rotation or sticky sessions from 30 seconds to 36 hours, and HTTP, HTTPS and SOCKS5 on one gateway; the browser profile on top of it is yours to keep consistent. More on the split in what proxies can and cannot fix.

Need IPs that match your browser profiles? ProxyField residential proxies cost $2.95/GB for 1 GB down to $1.95/GB from 1,000 GB, with no subscription. Start with the Easy Trial (1 GB); traffic never expires, and all purchases are final.

Sources

Canvas and WebGL Fingerprinting FAQ

What is a canvas fingerprint?

ProxyField's 412M+ residential IPs change the IP address a site sees, not your canvas fingerprint: a canvas fingerprint is a short hash of a test image your browser draws on a hidden HTML5 canvas. Fonts, graphics drivers and GPUs render the image slightly differently, so the hash varies between setups but stays the same on one device. Sites use it, with other signals, to recognize a browser without cookies.

How does canvas fingerprinting work?

A script draws a fixed scene of text, emoji and semi-transparent shapes on a canvas element, often invisible, then reads the pixels back with toDataURL() or getImageData(). Tiny differences in font rendering, anti-aliasing and color blending make those pixels differ between operating systems, drivers and GPUs. The script hashes the result and compares the hash with earlier visits and with the device the browser claims to be.

How does hashing work in canvas fingerprinting?

The script turns the long image data, often a base64 data URL thousands of characters long, into a short fixed-length value with a hash function, such as a 32-bit hash or SHA-256. Identical pixels always give the same hash and a single changed pixel gives a different one, so the hash works as a compact ID for how your machine draws. Only the hash is stored and compared, not the image.

What is a WebGL fingerprint?

It is a fingerprint built from the browser's 3D graphics API: the graphics card's vendor and renderer names, its capabilities such as texture limits and supported extensions, and often the hash of a rendered 3D scene. It identifies the GPU and driver more directly than a canvas hash, and like the canvas hash it stays the same when you change your IP address.

How does WebGL fingerprinting work?

A script opens a WebGL context on a canvas, asks for parameters with getParameter() and getSupportedExtensions(), reads the unmasked vendor and renderer through the WEBGL_debug_renderer_info extension where the browser allows it, and may render a 3D scene and hash its pixels. The combined values are hashed into one WebGL fingerprint.

What information is collected through WebGL fingerprinting?

The GPU vendor and model, the graphics API and driver path (for example ANGLE on Direct3D, Metal or Vulkan), limits such as the maximum texture size and shader precision, the list of supported WebGL extensions, and the pixel output of a test scene. None of it includes your name or files, but together it narrows down your hardware.

Why is WebGL fingerprinting hard to spoof?

Because the values must agree with each other and with the rest of the browser: a renderer string can be replaced, but the rendered pixels, the extension list and the performance still come from the real GPU. A claimed graphics card that draws like a software renderer, or values that change between two reads, are signals in themselves.

How do I block canvas fingerprinting?

Use a browser with built-in protection: Brave randomizes canvas and other values per site and per session, and Firefox's privacy.resistFingerprinting setting hides details such as the WebGL renderer. Safari adds noise to fingerprintable APIs in Private Browsing and, since Safari 26, keeps known fingerprinting scripts from reliably reading canvas and similar APIs in every window. Blocking canvas entirely can break sites that draw charts or maps, and a blocked or noisy canvas is itself rare, so it protects against tracking across sites better than it hides you.

What should I check in a browser fingerprint test?

Look at the canvas and WebGL lines first: whether the canvas hash is unique in the test's sample, whether the WebGL renderer names a real GPU, and whether the values stay the same when you reload. Then check that the time zone, language and user agent agree with your IP's location and with each other. Rare values and contradictions are what make a fingerprint stand out.

Does a proxy change my canvas or WebGL fingerprint?

No. A proxy changes the IP address and its location; the canvas hash and the WebGL values come from your browser and hardware, and they stay the same through any proxy or VPN. To change them you need another browser profile or device, and that profile should match the proxy's location in time zone and language.

Show 1 more questionShow fewer questions

Why do headless browsers give themselves away through WebGL?

Because headless browsers on servers usually have no GPU and fall back to a software renderer such as SwiftShader or llvmpipe, which shows up in the WebGL renderer string. In our test, headless Chromium 156 on a Linux server reported a SwiftShader renderer, which an ordinary Windows or Mac desktop never reports. Running a full browser on a machine with a real GPU, or a consistent emulated profile, avoids the mismatch.

Easy Trial: 1 GB for $2.95.

Try for the price of 1 GB, no subscription, traffic never expires.