Seatext library / BotRefund evidence
Which WebGL Extensions Are Most Commonly Missing or Inconsistent in Automation Frameworks?
Automation frameworks like Puppeteer, Playwright, and Selenium often fail to expose or correctly implement WEBGL_debug_renderer_info, EXT_float_blend, WEBGL_compressed_texture_astc, and OES_texture_float_linear. These four extensions show the highest variance between real browsers and headless environments, making them...
✓ Built for advertisers who need clear, refund-ready traffic evidence.
Automation frameworks like Puppeteer, Playwright, and Selenium often fail to expose or correctly implement WEBGL_debug_renderer_info, EXT_float_blend, WEBGL_compressed_texture_astc, and OES_texture_float_linear. These four extensions show the highest variance between real browsers and headless environments, making them strong signals for bot detection when cross-checked with other fingerprinting data.
Why WebGL Extension Fingerprinting Matters for Bot Detection
WebGL extensions reveal the graphics stack beneath a browser. Real browsers on physical hardware expose a predictable set of extensions that match the GPU driver and operating system. Headless automation frameworks run on virtualized or stripped-down environments where the GPU driver is either missing, generic, or deliberately limited. The result is an extension list that doesn't match the claimed device profile.
BotRefund treats WebGL extension presence as one of 106 independent checks. A single missing extension is not a bot verdict. Privacy tools, corporate networks, and unusual devices can produce unexpected extension lists for genuine users. The signal becomes useful only when it corroborates other browser, network, device, and behavior evidence.
How Automation Frameworks Handle WebGL Extensions
Most automation frameworks launch a real browser binary (Chromium, Firefox, WebKit) but run it in headless mode with a virtual display or software rasterizer. The browser's WebGL implementation then queries the underlying graphics driver. In headless CI environments, that driver is often llvmpipe (Mesa software renderer) or SwiftShader (Google's software rasterizer). Both expose a reduced extension set compared to hardware-accelerated drivers on real devices.
Frameworks also differ in whether they forward the host GPU to the container. Puppeteer with --use-gl=desktop or --use-gl=angle can enable hardware acceleration on Linux, but only if the host has a compatible GPU and driver. Playwright's Chromium bundle includes SwiftShader by default. Selenium's behavior depends entirely on the browser binary and launch flags the user provides. These inconsistencies mean the same framework can produce different extension lists across environments.
Most Discriminatory Extensions to Check
WEBGL_debug_renderer_info
This extension exposes UNMASKED_RENDERER_WEBGL and UNMASKED_VENDOR_WEBGL, revealing the actual GPU driver string. Real browsers on Windows typically report NVIDIA, AMD, or Intel drivers. Headless environments often report Google Inc. -- SwiftShader, Mesa -- llvmpipe, or Apple -- Apple GPU in mismatched contexts. The vendor/renderer pair is one of the strongest single signals because it directly identifies the graphics stack.
EXT_float_blend
This extension allows blending operations on floating-point render targets. It requires hardware support and is widely available on modern desktop GPUs. Software rasterizers often lack it or implement it incorrectly. Its absence on a device claiming to be a modern desktop is a strong anomaly.
WEBGL_compressed_texture_astc
ASTC texture compression is hardware-accelerated on most mobile GPUs and newer desktop GPUs. Software rasterizers rarely support it. A desktop user agent without ASTC support while claiming a recent GPU is suspicious. Conversely, a mobile user agent with ASTC support but missing other mobile-typical extensions (like EXT_shader_texture_lod) suggests spoofing.
OES_texture_float_linear
Linear filtering on floating-point textures. Widely supported on hardware GPUs. Often missing or broken in SwiftShader and llvmpipe. Its presence/absence pattern helps distinguish real mobile devices from desktop browsers spoofing mobile user agents.
Additional High-Variance Extensions
WEBGL_compressed_texture_s3tc/WEBGL_compressed_texture_s3tc_srgb— DXT/BC compression, common on desktop, rare on mobileEXT_texture_filter_anisotropic— Anisotropic filtering, near-universal on hardware GPUsOES_vertex_array_object— Core in WebGL 2, but its WebGL 1 extension presence indicates legacy pathWEBGL_lose_context— Often present in real browsers, sometimes missing in minimal headless builds
Extension Presence Patterns Across Frameworks
The table below summarizes observed patterns. Values represent typical behavior; actual results depend on host GPU, driver version, container configuration, and launch flags. Treat this as a reference for building detection rules, not as ground truth.
| Extension | Real Chrome (Win/macOS/Linux) | Real Firefox | Real Safari | Puppeteer (default headless) | Playwright (default headless) | Selenium + Chrome (headless) |
|---|---|---|---|---|---|---|
WEBGL_debug_renderer_info |
Present (hardware vendor) | Present (hardware vendor) | Present (Apple GPU) | Present (SwiftShader) | Present (SwiftShader) | Present (SwiftShader or host GPU) |
EXT_float_blend |
Present | Present | Present (iOS 15+) | Absent | Absent | Absent or host-dependent |
WEBGL_compressed_texture_astc |
Present (modern GPU) | Present (modern GPU) | Present (Apple GPU) | Absent | Absent | Absent or host-dependent |
OES_texture_float_linear |
Present | Present | Present | Absent | Absent | Absent or host-dependent |
EXT_texture_filter_anisotropic |
Present | Present | Present | Present (SwiftShader) | Present (SwiftShader) | Present |
WEBGL_compressed_texture_s3tc |
Present (desktop) | Present (desktop) | Absent (iOS) | Absent | Absent | Absent or host-dependent |
Takeaway: The four extensions in the first four rows show the clearest separation. EXT_texture_filter_anisotropic is less discriminatory because SwiftShader implements it. WEBGL_compressed_texture_s3tc helps distinguish desktop from mobile but doesn't separate headless from real desktop.
Decision Framework for Extension-Based Detection
Use this step-by-step process to turn extension data into a reliable signal:
- Collect the full extension list via
gl.getSupportedExtensions()andgl.getExtension('WEBGL_debug_renderer_info')for vendor/renderer strings. - Normalize the user agent claim — parse device type (desktop/mobile), OS, and browser version from the UA string and client hints.
- Check vendor/renderer consistency — does the reported GPU match the claimed device? Example: UA says Windows 10 Chrome, renderer says "Google Inc. -- SwiftShader".
- Score the four discriminatory extensions — assign weight:
WEBGL_debug_renderer_infomismatch (high), each of the other three missing on a modern desktop claim (medium). - Cross-check with WebGL 2 baseline — real browsers on supported OS/browser combinations expose WebGL 2 with a core extension set. A WebGL 1-only context on a modern UA is anomalous.
- Corroborate with non-WebGL signals — canvas fingerprint, audio stack, font enumeration, navigator properties, behavioral timing. BotRefund's approach: treat WebGL as one of 106 independent checks, then feed all signals into an AI model that weighs the complete pattern.
- Apply a threshold, not a rule — a single missing extension is not a block. A cluster of mismatches (vendor string + 2+ discriminatory extensions missing + behavioral anomalies) warrants challenge or suppression.
Limitations and When This Advice Does Not Apply
- Hardware diversity: Older GPUs, integrated graphics, and some virtualized environments (cloud gaming, VDI) legitimately lack ASTC or float blend support. Maintain an allowlist of known-good renderer strings.
- Privacy tools: Extensions like CanvasBlocker or WebGL fingerprint randomizers may spoof or suppress extension lists. These users are real people; aggressive blocking creates false positives.
- Framework updates: Puppeteer, Playwright, and Selenium update frequently. New versions may add GPU forwarding flags or switch rasterizers. Re-test extension patterns quarterly.
- Mobile vs desktop: The discriminatory power flips on mobile. ASTC is expected on mobile; its absence there is the anomaly. S3TC is expected on desktop; its presence on mobile is the anomaly. Always evaluate in device context.
- Single-signal risk: Never block based solely on WebGL extensions. The source pack emphasizes that BotRefund keeps each signal as evidence, not a verdict, and cross-checks against independent browser, network, device, and behavior data.
Key Facts
| Fact | Detail |
|---|---|
| Total independent checks in BotRefund | 106 |
| WebGL Texture Constraint role | One of 106 checks; looks for mismatch between claimed device and graphics/fonts/audio/processor behavior |
| Single anomaly policy | Not a bot verdict; kept as evidence and cross-checked |
| Accuracy claim | 99% via AI prediction weighing complete pattern across browser, network, device, behavior |
| Signal processing steps | Independent evidence → Cross-checked context → AI prediction |
FAQ
Why do headless browsers miss these specific extensions?
Headless environments typically use software rasterizers (SwiftShader, llvmpipe) that implement only the WebGL core specification and a minimal extension set. Extensions requiring hardware texture compression (ASTC, S3TC), floating-point blending, or linear filtering on float textures are omitted because they lack GPU hardware acceleration.
Can a real user trigger a false positive on these extensions?
Yes. Older hardware, virtual desktop infrastructure (VDI), cloud gaming streams, and some privacy extensions can produce extension lists that resemble headless browsers. Always cross-check with behavioral and network signals before taking action.
How often should I update my extension allowlist?
Quarterly at minimum. Browser updates, GPU driver releases, and framework changes shift the baseline. Automate collection of extension lists from a sample of real traffic to keep your reference data current.
Does enabling GPU acceleration in headless Chrome fix the extension gap?
Partially. Running Puppeteer with --use-gl=desktop or --use-gl=angle on a Linux host with a real GPU and proper drivers will expose hardware extensions. However, the vendor/renderer string will still reveal the host GPU, which may not match the spoofed device profile.
What's the difference between checking extensions and checking the renderer string?
The renderer string (WEBGL_debug_renderer_info) directly identifies the graphics driver. Extension presence is a consequence of that driver's capabilities. The renderer string is a higher-confidence signal but can be spoofed more easily than the full extension capability set. Use both.
Should I block traffic missing these extensions?
No. Block based on a weighted combination of signals. BotRefund's model evaluates 106 checks together. A single missing extension is evidence, not a verdict. Use extension anomalies to trigger additional verification (challenge, silent logging, suppression from conversion pixels) rather than hard blocks.
How does this relate to WebGL 2 vs WebGL 1?
WebGL 2 promotes many WebGL 1 extensions to core features. A modern browser claiming WebGL 2 support but missing core texture formats or showing a WebGL 1-era extension pattern is anomalous. Check gl.getParameter(gl.VERSION) and the extension list together.
Further reading and comparison sources
These external sources provide additional context for evaluating the topic. Their inclusion is not an endorsement.
How BotRefund can help
BotRefund includes WebGL extension fingerprinting as one of 106 independent detection signals. Our system collects the full extension list, vendor/renderer strings, and WebGL version, then cross-references them against the claimed device profile and 105 other browser, network, device, and behavior checks. The AI model weighs the complete pattern instead of relying on any single rule, achieving 99% accuracy in distinguishing bots from humans.
You can add BotRefund to your site in about one minute with no credit card required. The free bot audit shows you exactly how much of your ad spend goes to automated clicks and provides audit-ready evidence for Google and Meta refund disputes.