Why per-surface randomization fails
The naive approach is to randomize each fingerprint surface independently — a different canvas hash, a different WebGL string, a different font list. The result is a combination no real device would ever produce: a macOS user-agent with a Linux font set, an NVIDIA GPU string with a Mac screen aspect, an Asia/Tokyo timezone with US English. Anti-bot models trained on millions of real users flag these impossibilities instantly. The fingerprint itself becomes the tell.
Runtime spoofing vs engine-level patching
The same patch can live at two different layers, with very different durability:
| Runtime spoofing | Engine-level patching | |
|---|---|---|
| How it works | JS injected at page load overrides properties / methods | C++ source of Chromium / Firefox is patched and rebuilt |
| Examples | puppeteer-extra-stealth, undetected-chromedriver, selenium-stealth | Camoufox, CloakBrowser, PatchRight (patches at Playwright source) |
| Defeats toString check? | No — the patch is a JS function, visible via Function.prototype.toString() | Yes — the override happens below the JS layer, so toString still returns "[native code]" |
| Setup cost | npm install | Binary download (Camoufox/CloakBrowser) or pip install (PatchRight) |
| Maintenance | Plugin updates as detections change | Tied to upstream Chromium/Firefox releases; weeks-to-months lag |
Runtime spoofing is the cheaper starting point and is sufficient against simpler vendors (Cloudflare Bot Fight Mode, Imperva, AWS WAF Common). Engine-level patching is required for Kasada, recent Akamai, Cloudflare Bot Management Enterprise, PerimeterX, and F5 Shape — see the vendor cheatsheet for which deployments fall in which category.
The real-profile-database approach
The hardest part of evasion isn't hiding individual signals — it's making them coherent. A browser claiming to be Chrome on Windows 11 with an NVIDIA renderer must have the matching extension list, the matching AudioContext output for that OS, the matching timezone for the claimed IP geolocation, and so on across dozens of surfaces. Hand-spoofing each surface independently almost always produces an incoherent combination.
The state-of-the-art approach is the real-profile database: harvest tuples of (UA, OS, GPU, audio, canvas, timezone, language, screen size, …) from real users at scale, then serve one tuple per scraper session. Camoufox bundles such a database (10k+ profiles); commercial anti-detect browsers like Multilogin and GoLogin maintain larger ones. The advantage is that every signal is internally coherent — they were collected together from one real machine.
The catch is novelty. Anti-bot vendors test against the same scraping tools and harvest their profile databases. A profile that's been published in Camoufox's corpus for six months may already be flagged. Refreshing the database is the work — collecting profiles, rotating them out before they burn, and matching profile geography to proxy geography. This is why commercial anti-detect tools charge $50-200/month for the same idea Camoufox ships free: the operational cost of profile freshness, not the patching itself.
Whole-profile rotation
The correct unit of rotation is a complete device profile: a coherent set of (UA, fonts, GPU, screen, timezone, languages, TLS) that matches a real device class. Tools like Camoufox ship with curated profile pools. Custom rotation needs a profile generator that respects the joint distribution — e.g., a Windows + Chrome profile always has the same set of installed fonts, the same TLS ciphersuite order, the same audio context hash range.
What evasion does not cover
A perfect static fingerprint is necessary but not sufficient. Behavioral signals (mouse movement, scroll velocity, dwell time) are evaluated separately and can fail even a perfectly evaded browser. IP reputation runs before fingerprinting and discards datacenter traffic before the JS even loads. Evasion is one layer in a stack; the others have to be handled too.
