In 2026, IP reputation is a necessary but no longer sufficient defence for any cloaker. The decisive battle has moved into the browser itself. Modern detection works by extracting a high-dimensional fingerprint from the visitor's runtime environment and comparing it against a corpus of known-bot and known-human fingerprints. This article walks through the engineering of the four main fingerprinting techniques cloakers use today — canvas, WebGL, audio context, and font enumeration — explains the headless-browser tells that give reviewers away, and outlines the behavioural and ML pipelines layered on top.
1. The Fingerprinting Premise
The premise is simple: every browser, on every device, exposes a wide surface of measurable properties. Some are explicit (User-Agent, screen size, language). Others are implicit, leaking through how the browser renders, computes audio, enumerates fonts, or executes JavaScript timing. Combine 30–50 of these properties and the joint entropy is high enough to identify the visitor's environment class — not their identity, but the category of system they are running on.
For cloaker detection we don't need to identify the human; we need to classify the environment. "Real Chrome on a real macOS laptop with a real GPU" is one class. "Headless Chromium on a Linux EC2 instance with SwiftShader" is a very different class. The fingerprint draws the line.
For broader context on why this matters, see our complete guide to ad cloaking and the Facebook ad review pipeline breakdown.
2. Canvas Fingerprinting
Canvas fingerprinting was first published by Mowery and Shacham in 2012 and remains one of the most reliable browser fingerprinting techniques. The idea: instruct the browser to render a specific 2D scene — text in a specific font, geometric shapes, colour gradients — into an off-screen <canvas> element, then hash the resulting pixel buffer. Because the rendering pipeline depends on the operating system, GPU driver, anti-aliasing settings, and font availability, even subtle environmental differences produce different pixel output and therefore different hashes.
A typical implementation:
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
ctx.textBaseline = 'top';
ctx.font = '14px "Arial"';
ctx.fillStyle = '#f60';
ctx.fillRect(125, 1, 62, 20);
ctx.fillStyle = '#069';
ctx.fillText('IPCloak.ai \u2728 fp', 2, 15);
const dataURL = canvas.toDataURL();
const hash = await sha256(dataURL);
Real consumer hardware produces a wide distribution of canvas hashes — popular Apple silicon Mac configurations cluster around a few common values, but Windows machines vary substantially based on GPU and driver. Headless Chromium on Linux running SwiftShader (the software rasteriser) produces a small set of universally-known fingerprints. Catching them is a matter of maintaining a dictionary of known headless hashes and flagging any visitor that matches.
3. WebGL & GPU Fingerprinting
WebGL exposes the underlying graphics stack much more directly than 2D canvas. Two specific calls give a cloaker enormous signal:
const gl = canvas.getContext('webgl');
const dbg = gl.getExtension('WEBGL_debug_renderer_info');
const vendor = gl.getParameter(dbg.UNMASKED_VENDOR_WEBGL);
const renderer = gl.getParameter(dbg.UNMASKED_RENDERER_WEBGL);
Common signatures we observe in real human traffic:
Apple Inc. / ANGLE (Apple, ANGLE Metal Renderer: Apple M2, Unspecified Version)Google Inc. (NVIDIA) / ANGLE (NVIDIA, NVIDIA GeForce RTX 3060 Direct3D11 vs_5_0 ps_5_0, D3D11)Google Inc. (Intel) / ANGLE (Intel, Intel(R) Iris(R) Xe Graphics Direct3D11 vs_5_0 ps_5_0, D3D11)
Common signatures of headless infrastructure:
Google Inc. (Google) / ANGLE (Google, Vulkan 1.3.0 (SwiftShader Device (Subzero) (0x0000C0DE))WebKit / WebKit WebGL(puppeteer pre-Chromium-110)Mesa / llvmpipe (LLVM 15.0.7, 256 bits)- Empty or null vendor/renderer strings (a major red flag — real browsers always populate these)
SwiftShader and llvmpipe are software rasterisers used when a real GPU is unavailable. They are de facto signatures of a headless or virtualised environment. Modern reviewer fleets increasingly run on real GPU instances to defeat this — but those signatures cluster too, since cloud providers offer a small set of GPU SKUs.
4. AudioContext Fingerprinting
Audio fingerprinting was introduced by the original Mowery paper and refined heavily by FingerprintJS. The technique exploits the fact that processing a known audio signal through the browser's OfflineAudioContext produces output that depends on the underlying audio implementation, which varies across OS and browser combinations.
const ctx = new OfflineAudioContext(1, 44100, 44100);
const osc = ctx.createOscillator();
osc.type = 'triangle';
osc.frequency.value = 10000;
const compressor = ctx.createDynamicsCompressor();
compressor.threshold.value = -50;
compressor.knee.value = 40;
osc.connect(compressor);
compressor.connect(ctx.destination);
osc.start(0);
const buffer = await ctx.startRendering();
const sum = buffer.getChannelData(0).slice(4500, 5000).reduce((a,b)=>a+Math.abs(b), 0);
The resulting sum value is consistent within an environment but varies between environments. Headless Chromium on Linux returns a small cluster of values (~124.0434 on common configurations). Real macOS Safari returns a different cluster (~35.7383). Mobile Chrome on Android returns yet another. The dimensionality is low (one float) but combined with the other signals it adds useful discriminatory power.
5. Font Enumeration
Browsers do not expose an enumerate-fonts API directly. Cloakers infer the installed font set indirectly by attempting to render text in a target font and comparing the resulting metrics against a fallback. If Helvetica Neue renders identically to monospace, Helvetica Neue is not installed. If it renders differently, it is installed.
Run this against ~120 common fonts and you have a font fingerprint with strong signal. Real consumer machines have an idiosyncratic font set: macOS ships with around 230 fonts by default, Windows ships with 110, Linux distributions ship with 50–80 depending on distro. Headless Chromium on a stripped-down Linux container often has fewer than 30. A "real Chrome on real macOS" advertisement that returns 28 fonts is almost certainly a headless impostor.
Specific tells we look for:
- Font count under 40 → likely headless Linux
- Presence of
DejaVu Sans+ absence ofApple Color Emojiclaiming to be macOS → impostor - Presence of
Liberation Sansclaiming to be Windows → impostor
6. Headless Browser Tells
Beyond the rendering fingerprints, headless Chromium leaks dozens of subtle environmental tells that automation libraries try (and frequently fail) to patch out. The classic ones:
navigator.webdriver === true— set by default when Chromium is launched in automation mode. Puppeteer-stealth patches this toundefined, but does so via adefinePropertytrap that is itself detectable.window.chromeobject missing or anomalous. Real Chrome populates an extensivechromeobject with subobjects likeapp,runtime,loadTimes. Headless Chromium often has a sparse or missing version.Notification.permission === 'denied'by default in headless mode, while real browsers default to'default'.- Inconsistencies in
navigator.plugins.length(headless reports 0, real Chrome reports 3–5 even with no third-party extensions). - Mismatch between User-Agent claim and
navigator.platform. UA says macOS, platform says Linux x86_64 → impostor. - Anomalous timing in event handlers. Headless event loops run with predictable, low-jitter timing. Real browsers exhibit micro-variance from competing processes.
- Missing
PermissionsAPI or always-granted permissions. - Presence of automation framework artefacts like
__nightmare,callPhantom,_phantom,__webdriver_evaluate,__selenium_evaluate,__driver_evaluate.
None of these is conclusive on its own — sophisticated review fleets patch the obvious ones. But the joint distribution across 30+ tells produces a discrimination accuracy in the high 90s.
7. Behavioural Signals
The next layer up from environment fingerprinting is behaviour. Real users move their mouse along curved trajectories with variable speed; bots move in straight lines with constant velocity. Real users scroll in bursts with pauses; bots scroll smoothly to the bottom. Real users tab around forms and occasionally tab back; bots fill fields in DOM order without revisits.
Specific signals our filter samples in the first 1.5 seconds of pageview:
- Mouse movement entropy (Shannon entropy of dx, dy deltas across sampling window)
- Touch event presence on a UA claiming mobile
- Scroll velocity profile (smooth-monotone vs human-jagged)
- Time-to-first-interaction (humans: 2–8 seconds; bots: under 500ms or above 30s)
- Focus / blur cadence on form fields
- WebGL frame rate under load (real GPUs sustain 60fps; SwiftShader drops to 12–25)
Behavioural detection is the part of the stack where reviewer-vs-real-user separation actually happens in 2026. The IP layer is mostly solved; the runtime layer is where the cat-and-mouse game lives.
8. ML Classifier Inputs
All of the above signals feed into a final ML classifier — typically a gradient-boosted tree (XGBoost or LightGBM) for low-latency inference, sometimes a small neural network if more nuanced interactions are needed. The feature vector for a single decision is roughly 80–120 floats, including:
- One-hot ASN / country / OS
- Hashed canvas / WebGL / audio fingerprints (collapsed to bucket IDs)
- Continuous behavioural metrics from Section 7
- Header-set entropy, accept-language consistency
- TLS / JA4 fingerprint bucket
- Historical risk score for the source IP and destination URL
The classifier outputs a single probability — visitor is bot vs visitor is human — and the cloaker's threshold (typically 0.5–0.65 depending on vertical risk tolerance) determines which page renders. Models are retrained weekly against fresh probe data and platform-side enforcement events.
9. FingerprintJS as a Reference Point
FingerprintJS is the open-source/commercial benchmark for browser fingerprinting. Their open-source library is widely used by anti-fraud vendors, ad networks, and — yes — by ad-platform reviewers themselves to identify suspicious traffic on landing pages. Studying FingerprintJS is studying the state of the art on the detection side.
For cloaker engineering, the practical implication is twofold. First, anything FingerprintJS can identify is something an ad-platform reviewer fleet can identify too — so cloaker fingerprinting must be at least as good as FingerprintJS to be effective. Second, ad reviewers may carry their own anti-fingerprinting countermeasures (browser extensions that randomise canvas output, for example), which mean a static fingerprint match isn't always conclusive — context matters.
The vendors competing in this space (see our Adspect vs TrafficShield vs IPCloak.ai comparison) all license or build something equivalent. The differential is in how the fingerprint signal is fused with IP, behaviour, and historical data.
Closing thought
Browser fingerprinting is the single most important capability separating 2026 cloakers from their 2018 ancestors. Operators who pick a cloaker without inspecting how it does fingerprinting are buying a partial product. Ask any vendor: "show me your headless detection accuracy on residential-proxy probes" — if they cannot give you a number, walk.
The detection arms race continues. Real GPU instances in cloud and ML-driven anti-fingerprinting on the reviewer side will both keep moving the goalposts. The best operators stay close to the engineering side of their cloaker vendor and demand visible proof of update cadence.
Want to see our fingerprinting stack in action?
IPCloak.ai ships canvas, WebGL, audio and font fingerprinting with daily model updates. Try it for 7 days at $10.
Contact engineering See pricingAbout this article
Editorial standards. Authored by IPCloak.ai engineering. Code examples are simplified illustrations of patterns from our production fingerprinting stack and from publicly available implementations (FingerprintJS open-source, MDN Web Docs). Specific accuracy numbers reflect our internal probe testing in Q1 2026.
Compliance note. Browser fingerprinting raises legitimate privacy considerations in regulated jurisdictions (GDPR Recital 30, CCPA). Operators deploying these techniques in regulated geographies should consult counsel and ensure visitor consent where required. This article is a technical explainer, not a recommendation to bypass any legal regime.
References. Mowery & Shacham (2012) "Pixel Perfect: Fingerprinting Canvas in HTML5"; Englehardt & Narayanan (2016) "Online tracking: A 1-million-site measurement and analysis"; FingerprintJS open-source library (github.com/fingerprintjs/fingerprintjs); MDN Web Docs on Canvas, WebGL, and AudioContext APIs. See also our cloak system principles and Facebook review breakdown.