← back to blog

What canvas and WebGL actually give away

Most people who start looking into anti-detect browsers hear “canvas fingerprinting” and “WebGL fingerprinting” thrown around like they’re the same thing. They’re related, but they measure different parts of your machine, and understanding the difference matters if you’re trying to figure out why a browser profile got flagged.

I run proxy infrastructure and cloud phones for multi-accounting work, and I test anti-detect browsers against real detection systems as part of that. Canvas and WebGL come up constantly because they’re two of the cheapest, most reliable signals a website can collect without asking permission for anything. No camera prompt, no location request, just a few lines of JavaScript that run the moment a page loads.

What canvas fingerprinting actually reads

The HTML5 canvas element is a drawing surface. A page can tell your browser to render text, shapes, or gradients onto an invisible canvas, then call toDataURL() or getImageData() to pull back the resulting pixels as raw data.

Here’s the part that makes it a fingerprint: the same drawing instructions don’t produce identical pixels on every machine. The final image depends on your GPU, your graphics driver, your operating system’s font rendering engine, anti-aliasing settings, and even how your specific browser build handles subpixel rendering. Two people running the same browser version on different hardware can get measurably different pixel output from the exact same canvas draw call.

A site hashes that pixel data into a short string. That hash becomes a stable identifier. Run the same script twice on the same machine and you get the same hash. Run it on a different machine and the hash changes. It’s tracking what specific combination of hardware and software rendered that image, which turns out to be distinctive enough on its own.

This is why canvas fingerprinting survives clearing cookies, switching IPs, and rotating user agents. It doesn’t live in storage anywhere you can delete. It’s regenerated from your actual rendering pipeline every time the script runs.

What WebGL adds on top

WebGL fingerprinting reads a different layer: the GPU itself, more directly.

A page can call getParameter() on the WebGL rendering context and pull back specifics like your GPU vendor and renderer string (Intel UHD Graphics, NVIDIA GeForce, Apple M-series GPU, whatever the underlying hardware reports), the exact list of supported WebGL extensions, maximum texture size, shader precision, and anti-aliasing capabilities. Some scripts go further and render an actual 3D scene, then hash the output the same way canvas fingerprinting hashes 2D pixels, because GPUs also render 3D shapes with small hardware-dependent variations.

The renderer string alone is often enough to narrow you down. “ANGLE (NVIDIA, NVIDIA GeForce RTX 4070 Direct3D11 vs_5_0 ps_5_0)” tells a detection script your GPU model, your rendering backend, and your OS family in one line. Combine that with the canvas hash and you’ve got two independent signals that both have to agree with each other, and with everything else in the fingerprint, or the profile looks assembled rather than organic.

That last point is the one people underestimate. Detection systems don’t just check if canvas and WebGL values look “spoofed” in isolation. They check if the whole fingerprint is internally consistent. A canvas hash that implies Windows font rendering paired with a WebGL renderer string that implies macOS is a bigger red flag than either signal alone.

Why noise alone doesn’t solve it

The most common defense against canvas and WebGL fingerprinting, and the one baked into most anti-detect browsers, is adding controlled noise to the pixel output. Instead of returning the raw, deterministic canvas result, the browser injects tiny random variations into the pixels before handing them back, so the hash changes between sessions even on the same physical machine.

This works against naive detection that just hashes canvas output and treats matching hashes across sessions as one identity. But it creates a different problem if it’s done badly. Real hardware noise has a specific statistical texture, it’s not uniformly random, it follows patterns tied to how anti-aliasing and subpixel rendering actually behave. Detection scripts that have seen enough real-world canvas output can sometimes tell the difference between “genuine hardware variance” and “noise a script injected,” especially if the noise is applied too uniformly across every pixel or doesn’t correlate with the rest of the fingerprint the way real rendering would.

The same logic applies to WebGL. Swapping the renderer string to claim a different GPU is straightforward. Making every other WebGL parameter, extension list, and shader behavior consistent with that claimed GPU is the harder part, and it’s where cheaper spoofing implementations tend to fall apart. If a profile claims to be an NVIDIA card but reports extension support or precision limits that only make sense for an Intel integrated GPU, that mismatch is detectable without needing to touch canvas at all.

How different tools approach the problem

Anti-detect browsers like Multilogin, GoLogin, Kameleo, AdsPower, and Dolphin Anty all handle canvas and WebGL spoofing as a core feature, but the depth of implementation varies and it’s not something you can judge from a feature list or a pricing page. The relevant questions when you’re actually evaluating one are:

Does it spoof canvas and WebGL together, consistently, or are they two separate settings that can drift out of sync with each other? A profile with a randomized canvas hash but a WebGL renderer string that never changes is still leaking a stable identifier through the second channel.

Does the noise pattern look like measurement variance or like a random number generator? This is genuinely hard to verify without running the profile against real fingerprinting test pages and comparing the output against known real-hardware samples, which is part of why I keep a rotating set of test pages in my own workflow rather than trusting a vendor’s claim at face value.

Does the fingerprint stay consistent across a session, or does it change on every page load? Real hardware doesn’t change its GPU mid-browsing-session. A canvas hash that shifts on every reload of the same page is arguably worse than no spoofing at all, because it signals automation rather than hiding it.

None of this makes a browser undetectable. Canvas and WebGL are two signals out of dozens that modern detection stacks combine, alongside things like font enumeration, audio context fingerprinting, timing attacks, and behavioral signals that have nothing to do with rendering at all. A tool that handles canvas and WebGL well can still get a profile flagged through a signal it doesn’t touch. Anyone telling you a browser makes you unbannable or invisible is selling you something, not describing how the technology works.

What to actually check before you trust a profile

If you’re setting up profiles for multi-accounting work, don’t take a vendor’s marketing copy as proof their spoofing holds up. Run the profile through a few independent fingerprinting test sites and look at the actual canvas hash and WebGL renderer string it reports. Check whether those values stay stable within a session and change between sessions. Check whether the claimed GPU, OS, and browser version are internally consistent with each other, not just individually plausible.

That kind of manual verification is tedious, but it’s the only way to know what a specific profile is actually leaking, versus what a settings panel claims it’s spoofing.

For more breakdowns like this on how browser fingerprinting actually works and hands-on notes on the tools that handle it, head back to the Anti-Detect Review homepage.

Get new guides and videos first — join the Telegram channel.

need infra for this today?