Anti-Bot

How Browser Fingerprinting Works

By the Scrappey Research Team

What Is Browser Fingerprinting Evasion? — conceptual illustration
On this page

Browser fingerprinting is how a site combines signals — canvas, WebGL, audio, fonts, navigator probes, TLS (the encryption layer behind https, which has its own identifying pattern) — into a single identifier for a browser. A fingerprint is the combined set of these signals, which together can identify one browser. For an automated browser used in authorized workflows on sites you own or are permitted to access, the practical concern is configuration consistency: an empty or contradictory fingerprint is itself unusual, while an internally consistent configuration that matches a real device behaves the way a normal browser would.

Quick facts

Surfaces to handleCanvas, WebGL, audio, fonts, navigator, screen, timezone, TLS, HTTP/2
Hardest constraintCross-surface consistency (Mac UA + Linux fonts = block)
Recommended toolsCamoufox, PatchRight, Brave, undetected-chromedriver
Anti-patternRandomizing each surface independently — produces impossible combinations
Rotation strategyWhole-profile rotation, not per-surface randomization

Why per-surface randomization fails

The obvious-but-wrong approach is to randomize each fingerprint surface on its own — a random canvas hash here, a random WebGL string there, a random font list. The problem is that these signals are not independent in real life, so random combinations produce a device that could not exist: a macOS user-agent paired with a Linux font set, an NVIDIA GPU string on a Mac screen aspect ratio, an Asia/Tokyo timezone with US English. Anti-bot models, trained on millions of real users, know these pairings never occur and flag them instantly. The disguise becomes the giveaway.

Runtime spoofing vs engine-level patching

The same fix can live at two different layers, and where it lives decides how well it holds up:

Runtime spoofingEngine-level patching
How it worksJS injected at page load overrides properties / methodsC++ source of Chromium / Firefox is patched and rebuilt
Examplespuppeteer-extra-stealth, undetected-chromedriver, selenium-stealthCamoufox, 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 costnpm installBinary download (Camoufox/CloakBrowser) or pip install (PatchRight)
MaintenancePlugin updates as detections changeTied to upstream Chromium/Firefox releases; weeks-to-months lag

Runtime spoofing means injecting JavaScript when the page loads to override the values a site reads. It is the cheap starting point and works fine against simpler vendors (Cloudflare Bot Fight Mode, Imperva, AWS WAF Common). Engine-level patching means editing and recompiling the browser's own C++ source so the fix sits below JavaScript, where detection scripts cannot see it. That deeper approach is what you need 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 a consistent configuration isn't any individual signal — it's making them coherent, meaning they all fit together the way they would on one real machine. A browser claiming to be Chrome on Windows 11 with an NVIDIA renderer must also have the matching extension list, the matching AudioContext output for that OS, a timezone that matches the IP's location, and so on across dozens of signals. Spoofing each one by hand almost always produces a combination that doesn't add up.

The state-of-the-art fix is the real-profile database: collect tuples — bundles of values that belong together — of (UA, OS, GPU, audio, canvas, timezone, language, screen size, …) from real users at scale, then hand one whole tuple to each browser session. Camoufox bundles such a database (10k+ profiles); commercial anti-detect browsers like Multilogin and GoLogin maintain larger ones. Because each tuple was captured together from one real machine, every signal in it is automatically consistent.

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 real 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 right thing to rotate is a complete device profile, not one value at a time: a coherent set of (UA, fonts, GPU, screen, timezone, languages, TLS) that matches a real class of device. Tools like Camoufox ship with ready-made profile pools. If you build your own rotation, the generator has to respect which values go together — for example, a Windows + Chrome profile always carries the same set of installed fonts, the same TLS ciphersuite order (the fixed sequence of encryption options the browser offers), and the same audio context hash range.

What fingerprinting does not cover

A consistent static fingerprint is only one layer of how detection works. Behavioral signals — mouse movement, scroll velocity, how long you linger on a page — are judged separately. And IP reputation runs first: datacenter traffic is often handled differently before the page's JavaScript even loads. The static fingerprint is just one signal among several that systems weigh.

Code example

python
# Camoufox ships with whole-profile fingerprints, not per-surface randomization.
from camoufox.sync_api import Camoufox

with Camoufox(
    headless=False,
    humanize=True,
    fingerprint='windows-chrome-recent',
    proxy={'server': 'http://user:pass@residential:port'}
) as browser:
    page = browser.new_page()
    page.goto('https://target.com')

Related terms

What Is Browser Fingerprinting?
Browser fingerprinting is a technique that identifies and tracks a visitor by combining dozens of small, observable characteristics of their…
What Is Camoufox?
Camoufox is a fork of Firefox with anti-fingerprinting patches applied at the C++ build level. That phrase matters: most anti-fingerprinting…
What Is Canvas Fingerprinting?
Canvas fingerprinting is a way for a website to identify your device by asking the browser to draw a tiny invisible image, then turning the …
What Is WASM Fingerprinting?
WebAssembly (WASM) fingerprinting is a newer anti-bot technique that identifies a browser by measuring how its actual CPU behaves, instead o…
How Do Websites Detect Web Scrapers?
Websites spot scrapers by gathering hundreds of small clues about each visitor, then scoring how human the whole picture looks. No single cl…
What Is the Chrome DevTools Protocol (CDP)?
The Chrome DevTools Protocol (CDP) is the low-level interface for instrumenting and controlling Chromium-based browsers. Low-level means it …
What Is WebGL Fingerprinting?
WebGL fingerprinting reads identifying information directly from the GPU. WebGL is the browser feature that lets web pages draw 3D graphics …
What Is AudioContext Fingerprinting?
AudioContext fingerprinting plays a silent waveform through the Web Audio API, then reads back the resulting floating-point samples and hash…
What Is Function.toString() Inspection?
Function.prototype.toString() inspection is a technique anti-bot scripts use to identify JavaScript functions that have been modified at run…
Anti-Bot Vendor Detection Cheatsheet
A useful first step when working with any protected site you are authorized to access is identifying which anti-bot vendor sits in front of …
What Is a WebRTC IP Leak?
A WebRTC IP leak is when your browser quietly reveals your real IP address — even though you set up a proxy to hide it. It is the most-overl…
What Is PatchRight?
PatchRight is a browser-automation library that edits Playwright's own Python code before Chrome launches, instead of injecting JavaScript i…
What Is SeleniumBase?
SeleniumBase is a Python framework for automating and testing browsers, built on top of Selenium 4. Its two notable features, UC Mode and CD…
What Is Botasaurus?
Botasaurus is a free, open-source (MIT-licensed) Python framework for building web scrapers. You wrap your scraping functions with one of th…
What Is XDriver?
XDriver is a browser-automation tool for Playwright (a browser-automation library): one command swaps Playwright's internal driver files for…
What Is CloakBrowser?
CloakBrowser is a Chromium build with 49 C++ binary patches that give it a consistent browser configuration. The goal is for it to present l…
What Is Scrapling?
Scrapling is an all-in-one Python scraping framework that bundles fetching, parsing, anti-detection, and crawling behind one API — it is a l…
What Is Obscura?
Obscura is an open-source headless browser engine written from scratch in Rust — not a fork or patch of Chrome or Firefox. A headless browse…
Anti-Detect Browser Tools Compared
Anti-detect browser tools aim to present a consistent, real-looking browser configuration so that automated sessions render the same fingerp…
How Does Deobfuscation Work?
Deobfuscation is the process of turning deliberately unreadable code back into something a human can read and reason about. Obfuscators scra…
What Is WebGPU Fingerprinting?
WebGPU fingerprinting reads identifying data from the modern navigator.gpu API. WebGPU is the newest browser standard for talking to your GP…
What Is Client Hints Fingerprinting?
User-Agent Client Hints (UA-CH) are a set of structured HTTP headers plus a matching JavaScript API that report the same browser and operati…
What Is a Timezone / IP Mismatch?
A timezone/IP mismatch is when the location a browser claims and the location of its IP address disagree. Anti-bot systems (the software sit…
What Is navigator.webdriver?
navigator.webdriver is a standardized boolean that returns true when the browser is being controlled by automation. Think of it as a built-i…
What Is JA3 Fingerprinting?
JA3 is a method for fingerprinting a TLS client by hashing the fields of its Client Hello. TLS is the encryption layer behind https, and the…
What Is HTTP/3 / QUIC Fingerprinting?
HTTP/3 / QUIC fingerprinting identifies a client from the QUIC transport layer that HTTP/3 runs on. QUIC is the modern transport beneath HTT…
What Is Hardware Fingerprinting?
Hardware fingerprinting reads device capability signals - CPU cores, RAM, and screen metrics - that JavaScript exposes directly. These are v…
What Is CDP Detection?
CDP detection is the family of techniques anti-bot scripts use to tell that a browser is being driven through the Chrome DevTools Protocol (…
What Is Incognito Detection?
Incognito detection is the set of techniques that reveal whether a browser is in private / incognito mode. Private mode is the browser featu…
What Is Media Devices Fingerprinting?
Media devices fingerprinting reads the list of cameras, microphones, and speakers a browser reports via navigator.mediaDevices.enumerateDevi…
What Is Speech Synthesis Fingerprinting?
Speech synthesis fingerprinting reads the list of text-to-speech voices exposed by window.speechSynthesis.getVoices(). "Text-to-speech" mean…
What Is Stack Depth Fingerprinting?
Stack depth fingerprinting measures the maximum JavaScript recursion depth a browser allows before throwing a RangeError: Maximum call stack…
What Is CSS Media Query Fingerprinting?
CSS media query fingerprinting reads operating-system and device preferences through window.matchMedia(). A media query is a yes/no question…
What Is Screen Resolution Fingerprinting?
Screen resolution fingerprinting reads the display measurements a browser reports - screen.width/height, availWidth/availHeight, colorDepth,…
What Is Engine-Level (Blink) Browser Instrumentation?
Engine-level instrumentation means adding observation points inside the browser's C++ rendering engine (Blink), below the JavaScript layer, …

Concept map

How How Browser Fingerprinting Works connects

The terms most directly tied to this one. Hover a node to see its neighbours, click to preview, drag to rearrange.

0 terms · 0 connections
You are here · Anti-Bot
Building map…

Frequently asked questions

Is consistent fingerprinting the same as stealth mode?

Not quite — stealth tools are one approach. They adjust the known defaults in Puppeteer and Playwright. A consistent browser configuration is broader and also involves whole-profile rotation, behavioral realism, and matching transport-layer (network/TLS) fingerprints.

How often should I rotate fingerprints?

Per session, not per request. A real user keeps the same fingerprint for an entire visit, so changing it mid-session is itself a tell.

Can I use a real Chrome profile instead of patching?

Yes — driving real Chrome with a real user profile over CDP (the Chrome DevTools Protocol, the channel used to control the browser) avoids most patch-detection tells. The tradeoff is operational: managing real profiles at scale is hard, and you still need residential IPs and behavior emulation.

Should I always pick engine-level over runtime patching?

No — runtime patching is cheaper to deploy and is enough against roughly 80% of targets. Decide by testing, not by reputation: start with runtime (undetected-chromedriver or puppeteer-stealth plus a residential IP), measure your block rate, and move up to engine-level only if blocks exceed your budget. Reaching for Camoufox or CloakBrowser on an unprotected site just burns extra compute.

Why don't the engine-level tools just ship every browser version?

Forking Chromium or Firefox for every release is expensive. Camoufox tracks ESR Firefox; CloakBrowser tracks stable Chromium with a few weeks of lag. That lag is itself a fingerprint — a request claiming to be Chrome 134 from a tool actually running Chrome 131 has a mismatch between the User-Agent and the real engine, which sophisticated detection can catch.

Last updated: 2026-05-31