DEV Community

Cover image for Learn How to Dynamically Alter Canvas and WebGL Properties to Evade Headless Browser Detection
AlterLab
AlterLab

Posted on • Originally published at alterlab.io

Learn How to Dynamically Alter Canvas and WebGL Properties to Evade Headless Browser Detection

TL;DR

You can reduce headless browser detection by overriding canvas and WebGL properties through early JavaScript injection. This makes automated browsers mimic genuine user fingerprints without touching the target site's code.

Introduction

Modern anti-bot systems rely heavily on browser fingerprinting. Canvas and WebGL expose subtle differences between real browsers and headless variants. By programmatically adjusting these properties before a page loads, you lower the chance your scraper gets flagged. This guide shows how to do it responsibly with AlterLab’s web scraping API.

Why Canvas and WebGL Matter

Anti-bot vendors collect:

  • Canvas hash: the pixel output of a hidden drawing operation.
  • WebGL report: vendor, renderer, and supported extensions. Headless browsers like Chrome Headless often return static values (e.g., "Google Inc." for WebGL vendor) that differ from typical user machines. Changing these values to common, realistic strings reduces mismatch scores.

How to Alter Canvas Fingerprints

The canvas fingerprint is derived from drawing operations. Override HTMLCanvasElement.prototype.toDataURL or getContext to return a known-good data URL or to inject noise.

Example injection script:

```javascript title="canvas-override.js"
(function() {
const original = HTMLCanvasElement.prototype.toDataURL;
HTMLCanvasElement.prototype.toDataURL = function(type) {
if (type === 'image/png') {
// Return a deterministic PNG that mimics a common browser
return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==';
}
return original.call(this, type);
};
})();




## How to Alter WebGL Fingerprints
WebGL exposes `getParameter` calls for `VENDOR` and `RENDERER`. Replace the prototype method to return expected strings.

Example injection script:


```javascript title="webgl-override.js"
(function() {
  const getParameter = WebGLRenderingContext.prototype.getParameter;
  WebGLRenderingContext.prototype.getParameter = function(parameter) {
    if (parameter === 0x1F00) return 'Intel Inc.'; // VENDOR
    if (parameter === 0x1F01) return 'Intel Iris OpenGL Engine'; // RENDERER
    return getParameter.call(this, parameter);
  };
})();
Enter fullscreen mode Exit fullscreen mode

Practical Implementation with AlterLab

AlterLab allows you to attach custom JavaScript that runs before page evaluation. Use the scripts parameter to provide the overrides above.

Python SDK Example

```python title="scraper.py" {3-8}

client = alterlab.Client("YOUR_API_KEY")

Define the injection scripts

canvas_js = open("canvas-override.js").read()
webgl_js = open("webgl-override.js").read()

response = client.scrape(
url="https://example.com",
scripts=[canvas_js, webgl_js],
wait_for="networkidle"
)

print(json.dumps(response.json, indent=2))



Check out the [Python scraping API](https://alterlab.io/web-scraping-api-python) for a batteries-included client.

### cURL Example


```bash title="Terminal"
curl -X POST https://api.alterlab.io/v1/scrape \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "scripts": ["(function(){const o=HTMLCanvasElement.prototype.toDataURL;HTMLCanvasElement.prototype.toDataURL=function(t){return t===\"image/png\"?\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==\":o.call(this,t);}})();",
                "(function(){const g=WebGLRenderingContext.prototype.getParameter;WebGLRenderingContext.prototype.getParameter=function(p){if(p===0x1F00)return\"Intel Inc.\";if(p===0x1F01)return\"Intel Iris OpenGL Engine\";return g.call(this,p);}})();"
  ]'
Enter fullscreen mode Exit fullscreen mode

Step‑by‑Step Process

Best Practices and Ethical Considerations

  • Only scrape publicly accessible data; do not bypass authentication or paywalls.
  • Keep overrides within realistic ranges—extremely uncommon values can raise suspicion.
  • Rotate a small set of known-good fingerprints rather than generating random ones each request.
  • Monitor response codes and adjust if you see spikes in 403/429 responses.
  • Refer to the anti-bot handling documentation for built‑in mitigation layers.

Takeaway

By injecting small JavaScript snippets that normalize canvas and WebGL outputs, you make headless browsers blend with regular traffic. Combine this with AlterLab’s automatic retries, rotating proxies, and smart rendering to build scraping pipelines that stay under detection thresholds while respecting site policies. Start with a free account, test the overrides on a low‑risk endpoint, and scale as you verify success rates.

Top comments (0)