WebGL1 and WebGL2 report the same UNMASKED GPU
Check id webgl1-webgl2-coherence
What an ordinary browser yields
WebGL1 and WebGL2 return byte-identical UNMASKED vendor and renderer strings (or one context is unavailable, which reads N/A).
What a detector infers
The check creates a WebGL1 context and a WebGL2 context and reads UNMASKED_VENDOR_WEBGL / UNMASKED_RENDERER_WEBGL from each through the WEBGL_debug_renderer_info extension, then asserts the two contexts name the same GPU. The reason this catches spoofs is structural: in Chromium a WebGL1 context is a WebGLRenderingContext and a WebGL2 context is a WebGL2RenderingContext, and getParameter lives on two distinct prototypes. A stealth kit that hooks getParameter to rewrite the vendor/renderer often patches only one of those prototypes — usually WebGLRenderingContext — leaving the WebGL2 context reporting the real hardware. A detector reading both and finding them disagree learns the GPU string was rewritten at the JavaScript surface rather than being the true adapter, because a real machine's two context types are backed by the same driver and cannot disagree. Kasada reads webgl1_unmasked_vendor/renderer and webgl2_unmasked_vendor/renderer as separate probes for precisely this diff. The check reports N/A rather than failing when either context or the debug-renderer extension is unavailable, so a genuinely WebGL2-less or extension-stripped environment is never convicted.
How to resolve it
Spoof both WebGL context types or neither. A getParameter override must cover WebGLRenderingContext and WebGL2RenderingContext identically; better, set the GPU identity at the engine/driver level so both contexts derive from the same source and no per-prototype hook is needed.
Read in the wild by
Kasada
Collects the unmasked vendor/renderer from WebGL1 and WebGL2 as separate probes, which only matters if the two can disagree.
webgl1_unmasked_vendor / webgl1_unmasked_renderer vs webgl2_unmasked_vendor / webgl2_unmasked_renderer, plus gl_unmasked_vendor / gl_unmasked_renderer
Kasada ips.js teardown — the full 427-probe listEvery attribution traces to a published artifact. See the sources and their limits.
Nearby checks in Render & GPU
- WebGPU vendor coheres with WebGL vendor
webgl-webgpu-vendorTwo independent graphics stacks in the same browser are backed by the same physical adapter: this check lowercases the WebGL UNMASKED_VENDOR… - WebGL exposes a full parameter table + UNMASKED vendor/renderer
webgl-param-tableBeyond the two headline strings, a WebGL context answers getParameter for dozens of driver-specific limits. - WebGL vendor/renderer identical in a Worker
webgl-worker-vs-mainThe audit reads UNMASKED_VENDOR and UNMASKED_RENDERER on the main thread, then spawns a dedicated Worker that builds its own WebGL context… - masked WebGL VENDOR matches the engine
webgl-engine-vendorThis check reads the plain gl.getParameter(gl.VENDOR) — the masked value, not the debug extension's unmasked GPU string. - canvas readback is not noise-injected (1×1 probe)
canvas-tamperThe probe fills a single pixel with pure black on a 1x1 canvas and reads it straight back with getImageData. - one flat fill reads back as exactly one colour
canvas-flat-fill-uniformThis is the area form of the 1×1 canvas probe, and it exists because that probe is easy to pass by accident. - one pixel reads the same through a full read and a windowed read
canvas-subrect-consistencyThe same pixels, asked for twice through different windows. A full-canvas read and an inner 16×16 read overlap on 256 pixels, and those are… - a canvas reads back the same through toDataURL and getImageData
canvas-todataurl-vs-getimagedatatoDataURL and getImageData are two exits from one canvas, and PNG is lossless, so decoding the data URL back into pixels has to reproduce…
Clearcote is a browser built for fingerprint coherence
It is a Chromium fork, maintained by the same people who wrote this reference. It ships as a compiled browser rather than as a stealth script injected into someone else's — which is a description of how it is built, and is not an argument about how it behaves on this check.
This audit takes no position on how Clearcote scores on Render & GPU checks, on this one, or anywhere else. It has no baseline corpus of other people's fingerprints to rank you against and no vendor scoreboard — nearly every check is self-referential, asking one browser the same question through two independent APIs and reporting whether both answers can be true at once. It runs identically on any browser, including ours. Run it on yours and read the result yourself.
See the other checks in Render & GPU — the family webgl1-webgl2-coherence belongs to.