Stealth libraries can rewrite navigator.webdriver in under ten lines of code. They still can't rewrite how a human hand moves a mouse. That gap is the whole story behind headless browser detection in 2026: it stopped being a single JavaScript-property check and became a four-layer stack, and the top layer — behavioral scoring — now catches 98.2% of raw Playwright sessions that patch every obvious fingerprint.
The short version
navigator.webdriver Stopped MatteringFor years, the whole headless-detection conversation started and ended with navigator.webdriver. WebDriver sets it to true; stealth libraries overwrite it to undefined. Done, in a few lines.
That's still true. It's also mostly irrelevant now. Any bot running puppeteer-extra-plugin-stealth or a comparable patch already clears this check, according to cside's July 2026 breakdown of the signal hierarchy. Layer 1 checks — navigator.webdriver, navigator.plugins.length, window.chrome, the Permissions API — catch unsophisticated automation and nothing else. Against anything purpose-built, they produce what cside calls "low recall": the bot passes, and the site never knows.
Behavioral scoring does — specifically, cursor motion, scroll rhythm, and interaction timing that no automation library has reliably replicated at scale.
The reasoning is mechanical. A script calling mouse.move(x, y) jumps in a straight line or a scripted curve. A real hand produces micro-corrections, acceleration and deceleration that follow Fitts's law, and lateral drift no off-the-shelf path generator reproduces. cside trained a model, cursor_v2, on captured human sessions and scored automated traffic against that distribution. Result: 98.2% of raw Playwright sessions caught, 100% of stealth-mode browserless.io sessions caught, human false positives under 1%.
Scroll behavior tells a similar story. Humans scroll in short bursts with a natural velocity curve. Scripts calling window.scrollTo() or driving scroll through Chrome DevTools Protocol produce flat or step-function velocity — a shape that doesn't exist in recorded human interaction data.
| Layer | What it checks | Example signals | How hard to fake |
|---|---|---|---|
| 1. API checks | Browser-exposed JS properties | navigator.webdriver, window.chrome, Permissions API | Trivial — patched in one library import |
| 2. Rendering/GPU | Canvas + WebGL output | UNMASKED_RENDERER_WEBGL (SwiftShader vs. real GPU), font rasterization | Moderate — requires intercepting extension calls |
| 3. Network/transport | TLS and HTTP/2 fingerprints | ClientHello cipher order, frame ordering, header order | High — requires a modified browser build, not JS patches |
| 4. Behavioral | Session-level interaction data | Cursor micro-corrections, scroll velocity, timing distribution | Very high — no library reproduces it at scale |
Cross-signal mismatches close the remaining gap. A session claiming Chrome 120 on Windows while its WebGL renderer reports SwiftShader, or while its TLS fingerprint matches a headless Linux build, is internally contradictory in a way no real browser produces — and that contradiction is often the actual signal a detection system fires on, independent of any single layer.
Every evasion category targets a different layer, and none closes all four at once. puppeteer-extra-plugin-stealth handles Layer 1 — 19 patched signals — and stops there; it hasn't shipped a new release since 2023, while detection systems have shipped roughly three years of new signatures against it. Camoufox goes further by running Firefox's actual rendering and TLS stack instead of a patched Chromium, which is why Databay's independent testing in May 2026 flagged it as one of the only entries with clean detection scores.
Anti-detect browsers — Multilogin, AdsPower, LinkenSphere — take a different approach entirely: inject a full synthetic profile (fonts, GPU string, language, timezone) so each session looks like a distinct real device. That's an identity-layer strategy. It does nothing for Layer 4. Residential proxies solve a fifth problem — IP reputation — and likewise leave fingerprint and behavior untouched. Stack all three and you've addressed layers 1 through 3 plus network origin; the cursor still moves like a script.
This is the exact reason we've built DLBrowser around real interaction fidelity rather than fingerprint patching — a stealth runtime is only as good as its weakest layer, and for most of 2026's tooling that's the one layer patches can't reach.
Does navigator.webdriver still detect headless browsers in 2026?
No. It's the most widely patched signal — libraries like puppeteer-extra-plugin-stealth overwrite it to undefined in a few lines. It only catches unmodified Selenium or Playwright sessions with zero evasion layer applied.
What is cside's cursor_v2 model? A behavioral detection model trained on real human sessions that scores mouse-movement patterns — micro-corrections, acceleration, drift — against automated traffic. It catches 98.2% of raw Playwright sessions and 100% of stealth-mode browserless.io sessions at under 1% false positives.
Can Camoufox or anti-detect browsers beat behavioral detection? Camoufox improves rendering and network-layer scores by running Firefox's real stack instead of patched Chromium. Anti-detect browsers like Multilogin spoof identity signals. Neither reliably fakes cursor motion, scroll rhythm, or timing — the behavioral layer.
Why do TLS and HTTP/2 fingerprints matter for bot detection? They reflect the transport stack, not JavaScript. A headless Chromium session can patch its user-agent to claim desktop Chrome, but its TLS ClientHello and HTTP/2 frame ordering still match the underlying build — a mismatch that server-side detection can flag without touching the page's JS at all.
Track how these detection layers evolve on Dekrypt Labs Dispatches, and see the underlying research approach at Dekrypt Labs Research.
Abhishek Gupta is Co-Founder at Dekrypt Labs, building DLBrowser — a stealth browser runtime for real-world data collection. dekryptlabs.com