
Stealth Plugins Are Losing: The Browser Fingerprinting Evasion Arms Race
In February 2025, puppeteer-extra-plugin-stealth — the canonical browser stealth library for five years, the default for any Puppeteer-based scraper that needed to look human — stopped working against Cloudflare Business tier.
Not because Cloudflare patched a specific evasion. Cloudflare updated their detection model to identify the plugin's patch patterns. The same techniques that bypassed detection in January 2025 became the detection signature in February. The stealth plugin's README still claims "all fpscanner tests are now green, as well as all intoli tests." Those tests measure what the plugin patches. They don't measure what Cloudflare now looks for.
Call this the Stealth Half-Life: the window between a stealth tool's release and the detection systems learning to identify it. Based on the pattern of stealth tools rising and falling across 2020–2026, that window runs 6–18 months for JavaScript-patch plugins and 12–24 months for binary-patched browser forks. Neither number is a rule. Both are the observed spread.
We maintain scraping infrastructure for teams whose targets include Cloudflare Enterprise, DataDome, Akamai Bot Manager, and PerimeterX. The tool recommendations change quarter by quarter — not because last quarter's tools got worse, but because the detection side kept learning.
Three Detection Layers, Three Separate Arms Races
Anti-bot systems stack three orthogonal detection layers. A tool that defeats one is still detectable at the other two. Understanding which layer each tool operates on is the foundation for choosing the right stack.
Layer 1 — Network fingerprint. TLS ClientHello packet, HTTP/2 frame settings, header ordering. The anti-bot system reads this before any JavaScript runs. JA3 and JA4 fingerprint algorithms map the TLS handshake parameters to a hash; Python's default requests library produces one specific hash that every anti-bot system recognizes as non-browser. Real Chrome produces another. Tools like curl_cffi and curl-impersonate operate here.
Layer 2 — Browser fingerprint. navigator.webdriver, Chrome runtime objects, WebGL vendor, Canvas hashing, AudioContext hashing, font enumeration, screen resolution. JavaScript runs in the page's context and queries these attributes; the anti-bot system compares them against expected values and inconsistency patterns. Stealth plugins and patched browser forks operate here.
Layer 3 — Behavioral signals. Mouse movement curves, scroll velocity, typing cadence, click coordinate distribution, time-between-actions. DataDome's documentation names 35+ behavioral signals per session. The anti-bot system scores behavior against ML models trained on real user traces. No tool patches this — you can only generate better behavioral noise, and DataDome learns faster than the noise generators.
The failure mode teams hit: patch layer 2 with a stealth plugin, assume they're done, get blocked by layer 3 or layer 1. The plugin wasn't wrong. It was just solving the wrong problem.
The Three Generations of Stealth Tools
Generation 1: JavaScript-patch stealth plugins (2018–2024)
puppeteer-extra-plugin-stealth, playwright-extra stealth, selenium-stealth. These inject JavaScript patches into every page to overwrite fingerprintable attributes — navigator.webdriver = false, mock Chrome runtime objects, fake plugins array, spoof WebGL vendor. The patches run in the same JavaScript execution context the anti-bot system inspects.
What broke them: The patches themselves became detectable. Anti-bot systems stopped asking "is navigator.webdriver true?" and started asking "does the navigator object look monkey-patched?" ES6 Proxies have specific observable artifacts; so do synchronous mocks of the Chrome runtime. The plugin's patch signature — the structure of its Proxy handlers, the order of property overwrites, the specific fake values it uses — became the detection signal.
As Rebrowser documented (when the blog was accessible before moving to /404), the deeper issue is the Runtime.Enable CDP command that Puppeteer and Playwright call during initialization. This call tells anti-bot systems that an automation tool is connected to the browser — and JavaScript patches can't remove it.
Current status (April 2026): Works against basic bot protection (site-scrapers, simple rate limiting). Fails against Cloudflare Business and above, DataDome, PerimeterX/HUMAN. Usable for low-defended targets; deprecated for the hard 20% that drives most scraping complexity.
Generation 2: Patched browser forks (2022–present)
patchright for Python Playwright, rebrowser-puppeteer for Node, undetected-chromedriver for Selenium. Instead of patching JavaScript from outside, these modify the browser binary or the CDP layer directly.
Patchright's documentation lists the specific patches: "replaces Playwright's Runtime.enable with isolated ExecutionContexts to prevent JavaScript execution leaks," disables the Console API entirely, removes --enable-automation from Chrome launch args, adds --disable-blink-features=AutomationControlled. The Runtime.enable patch is the core move — it addresses the detection vector that Generation 1 couldn't touch.
Rebrowser-puppeteer takes the same approach for Node.js: patched Puppeteer fork that eliminates the Runtime.Enable leak at the CDP protocol level. Both projects claim to bypass Cloudflare, Kasada, Akamai, and DataDome.
What's starting to break them: Behavioral layer. Patched forks produce clean browser fingerprints but don't help when DataDome's ML model scores a scrape as "too linear, too fast, no hesitation between clicks." The forks themselves also carry patch signatures — isolated ExecutionContexts, for example, behave differently from real Chrome contexts in specific edge cases (DOM event timing under stress, garbage collection pauses during long-running scripts) that detection systems increasingly probe for.
Current status: The current best option for most teams. Patchright and rebrowser-puppeteer bypass Cloudflare Business reliably. Against Enterprise, they need residential proxies. DataDome goes both ways depending on the site's scoring threshold. PerimeterX requires behavioral mimicry on top. Expect the half-life to run 12–24 months before these patches become identifiable the way Generation 1's did — watch GitHub commit frequency as the leading indicator. A project that stops responding to Cloudflare updates is already dead.
Generation 3: No-WebDriver direct CDP (2024–present)
nodriver from the author of undetected-chromedriver. The architectural shift: no Selenium, no WebDriver layer, direct CDP connection to Chrome. The library connects to Chrome's debug protocol directly, bypassing every detection vector that targets WebDriver or WebDriver-derived automation stacks.
The nodriver README explains the advantage: "Direct communication provides even better resistance against web application firewalls (WAF's), while performance gets a massive boost." No ChromeDriver process to detect, no WebDriver wire protocol hops to fingerprint, fresh browser profile on each run. Fully async Python API.
The tradeoff is tooling maturity. Nodriver lacks the ecosystem around Playwright and Selenium — no Helm charts, fewer debugging tools, smaller Stack Overflow surface. Its cf_verify() method for Cloudflare Turnstile explicitly notes "english only" support. It's a tool for teams that prioritize detection resistance over developer ergonomics.
Current status: Strongest detection resistance among open-source tools in April 2026. Works against Cloudflare Business and Enterprise on most targets, handles DataDome's fingerprint layer cleanly. Still vulnerable to behavioral analysis at layer 3. Stealth Half-Life estimate: harder to predict because direct-CDP architecture changes what detection systems can see. Probably 18–36 months before detection catches up, assuming active maintenance.
What Actually Breaks a Stealth Tool
Every stealth tool dies for one of three reasons.
Pattern recognition. Cloudflare's ML models ingest billions of scrape attempts and learn the specific signature of each stealth tool — how the Proxy handlers are structured, which properties exhibit which patch artifacts, what the timing of Runtime.Enable calls looks like (or doesn't, when patched). When a tool hits critical adoption mass, the training signal becomes strong enough for the detection model to recognize it. Generation 1 stealth plugins hit this threshold around 2023. Generation 2 is approaching it.
Inconsistency exploitation. The FP-Scanner paper (Vastel et al., USENIX Security 2018) documented that modified fingerprints are detectable through inconsistency analysis. A scraper claiming to be Chrome 120 on macOS should have macOS-specific font lists, specific screen resolutions common on Apple hardware, specific TLS handshake parameters. Stealth plugins that patch one attribute without consistent patches elsewhere create inconsistencies that detection systems probe for.
Target-specific detection. Large targets with valuable data (LinkedIn, Amazon, Facebook, Glassdoor) commission custom detection tooling beyond the standard Cloudflare/DataDome stack. These targets use behavioral signatures specific to their site, scrape volume thresholds keyed to their traffic patterns, and dedicated teams updating detection weekly. A stealth tool that works against generic Cloudflare can still fail against LinkedIn's specific detection layer.
The useful-life estimate for any stealth tool correlates with its adoption curve. Obscure tools stay effective longer because there isn't enough aggregate scrape data for the detection model to learn their patterns. Popular tools draw fire — the more scrapers running puppeteer-extra-plugin-stealth, the richer Cloudflare's training data for detecting it. GitHub star count is a rough proxy for adoption, but deployment volume is what actually matters.
The Behavioral Layer Tools Don't Touch
Even with perfect fingerprint patching, a scrape that completes in 2 seconds with no mouse movement, zero scroll events, and click coordinates exactly at the center of button bounding boxes triggers DataDome's behavioral model. The DataDome documentation lists the specific signals: mouse trajectory curves, scroll velocity distribution, typing cadence between keydown events, idle time distribution, click coordinate variance.
Defeating this requires behavioral synthesis — programmatically generating human-like mouse paths, scroll patterns, and timing distributions. Open-source libraries exist: ghost-cursor for mouse trajectory generation, Crawlee's human-like fingerprints package. None of these beat DataDome's behavioral ML at the top tier. They raise the floor of behavioral realism from "obvious bot" to "suspicious but not immediately blocked."
The practical answer for behavioral detection is proxy + session design, not fingerprint tools. Residential proxies from pools with real human traffic (SOAX, Bright Data residential, Oxylabs residential) inherit the behavioral context of their IP space. Pairing Generation 2 or Generation 3 stealth with behavioral-aware proxy rotation raises the cost of detection past most sites' investment threshold. Cloudflare Enterprise customers and DataDome-protected targets still block at the margin.
The Operational Pattern That Still Works
Based on current (April 2026) stealth tool status:
For Python teams: patchright as the primary framework, nodriver as the escalation path for Cloudflare Enterprise targets. Residential proxies from a rotation pool. Structured output validation on every scrape to catch silent Cloudflare challenge pages returning 200 OK.
For Node.js teams: rebrowser-puppeteer as the primary. Migrate to a direct-CDP library if Cloudflare update cycles start invalidating patches faster than the project updates. Same proxy + validation discipline.
For targets with the hardest detection (LinkedIn, Facebook, Amazon): Assume no open-source stealth tool gives you durable access. Managed scraping APIs (Bright Data, Oxylabs Web Unblocker, ScrapFly) maintain dedicated teams that update detection evasion continuously. At these targets, the build-vs-buy math favors buy unless you have dedicated detection-evasion engineers.
Across all of the above: Budget for tool churn. Assume your primary stealth tool has a 12–24 month Stealth Half-Life and plan the rebuild before Month 18. The teams that get caught flat-footed are the ones who ship a Cloudflare-bypassing scraper in Month 1 and never touch it until it breaks in Month 14.
Need help with the detection arms race? Talk to an engineer — we architect scraping stacks with Generation 2 and Generation 3 stealth tools for teams hitting Cloudflare Enterprise, DataDome, and PerimeterX targets.
What This Analysis Cannot Tell You
Which specific stealth tool will still work on your specific target next quarter. The Stealth Half-Life estimate is a directional heuristic, not a guarantee. A Cloudflare update can shorten any tool's useful life to weeks if it targets that specific patch pattern — which is exactly what happened to puppeteer-extra-plugin-stealth in February 2025 and will happen to the tools currently on top of the ladder eventually.
The arms race is asymmetric. Defenders (anti-bot systems) train on aggregate data; attackers (stealth tools) deploy single releases and then iterate only when breakage becomes obvious. Detection gets better continuously. Evasion gets better in steps. The gap widens until a new generation of tools resets it.
Plan for the reset. Don't bet a production scraper on a single stealth tool's durability.
Frequently Asked Questions
Does puppeteer-extra-plugin-stealth still work against Cloudflare in 2026?
Not against Cloudflare Business or Enterprise. The plugin's patch patterns became detectable around February 2025 when Cloudflare updated their detection model to identify the specific ES6 Proxy signatures the plugin uses. It still works against basic bot protection (site-specific rate limiters, simple WAF rules) but is deprecated for any target running Cloudflare Bot Management above the Free tier.
What's the best web scraping stealth tool for 2026?
For Python: patchright as the primary, nodriver as the escalation for Cloudflare Enterprise. For Node.js: rebrowser-puppeteer. All three are Generation 2+ tools that patch the Runtime.Enable CDP leak — the detection vector that Generation 1 JavaScript-patch stealth plugins couldn't address. Pair with residential proxies and structured output validation.
What is browser fingerprinting and how do scrapers bypass it?
Browser fingerprinting reads attributes like navigator.webdriver, Canvas hashes, WebGL vendor, AudioContext output, and font lists to identify the client. Scrapers bypass it through patched browser forks (patchright, rebrowser-puppeteer) that modify these attributes at the browser binary or CDP protocol level, rather than through JavaScript patches that are themselves fingerprintable.
Can Cloudflare detect Playwright and Puppeteer in 2026?
Yes, by default. Vanilla Playwright and Puppeteer both call the Runtime.Enable CDP command during initialization, which Cloudflare's Bot Management identifies as an automation signal within milliseconds. Patched variants (patchright for Playwright, rebrowser-puppeteer for Puppeteer) remove this leak. Effectiveness against Cloudflare Business is consistent; Enterprise requires residential proxies layered on top.
How long do stealth plugins keep working before they get detected?
The Stealth Half-Life — useful life from release to widespread detection — runs 6–18 months for Generation 1 JavaScript-patch plugins, 12–24 months for Generation 2 patched browser forks, and potentially 18–36 months for Generation 3 direct-CDP tools like nodriver. The pattern is that detection systems train on aggregate data once a tool hits critical adoption, at which point patch signatures become identifiable.
Related posts

cURL vs. Playwright vs. LLM Scraper: A Decision Tree for 2026
Same scraping job costs $5, $150, or $6,000/month depending on the tool you pick. A 4-step decision tree for choosing between HTTP clients, headless browsers, and LLM-native scrapers in production.

Debugging Scrapers in Production: Logs, Screenshots, Video Replay, and Failure Forensics
Status codes aren't evidence. Screenshots, DOM snapshots, Playwright traces, and structured logs are. The Evidence Bundle pattern for turning scraper failures from hours of investigation into dashboard queries.

Playwright vs. Puppeteer vs. Selenium for Production Scraping: A 2026 Comparison
Most headless browser comparisons test on localhost. Production scraping at 100+ concurrent sessions reveals different winners — here's the data on memory, detection, and Kubernetes deployment.