navigator.webdriver and CDP detection: 9 checks Reddit runs

What Reddit's 9 platform health checks read, run verbatim on 8 September 2026 against a person, a bare CDP driver and our browser, and why webdriver is 1 of 17.

Davide Grasböck · Founder, Scalebrowser

Published Oct 18, 2026 · 6 min read

Short answer

A page detects the automation control plane through navigator.webdriver, traces a driver leaves in the page, and input no hand produced. Reddit ships 9 such checks in an 18,475-byte block of its bundle. Run verbatim on 8 September 2026, they flagged a bare CDP driver on its automation markers and found no pointer path before any of its 4 clicks. A Scalebrowser profile raised none of the 17 automation markers, and its one click without a full path was a repeated click on the same spot, which a person produced 4 times in 23 clicks.
9, checks Reddit runs, beside a block with nine round slots

Setting navigator.webdriver to false is the first thing every automation guide recommends, and it is the one change a detection script expects. The flag is a single value; the software that drives the browser leaves traces in several other places, and some of them grow when you hide the first one. We took the checks Reddit ships to every visitor, ran them unchanged against a person, a bare driver and our own browser, and counted what each one caught.

What is control plane detection?

Control plane detection is the search for the software that drives a browser, as opposed to the search for a browser that lies about itself. The W3C WebDriver specification created the most famous signal on purpose: navigator.webdriver "defines a standard way for co-operating user agents to inform the document that it is controlled by WebDriver". A driver that does not want to co-operate still leaves three kinds of trace behind.

  • Markers: the flag itself, globals a driver injects, such as the cdc_ prefix of chromedriver or Playwright's binding names, and the marks left by hiding them.
  • Protocol side effects: behaviour that changes because a DevTools client is attached, such as a console that reports to a listener or a tab that is attached but not in front.
  • Input without a hand: a click that arrives with no pointer movement before it, or key events that skip a step a keyboard always produces.

Which 9 checks does Reddit run?

Reddit runs 9 checks in a module it calls platform_health, and all 9 sit in one self-contained block of 18,475 bytes in the bundle every visitor downloads. On 8 September 2026 we lifted that block byte for byte, verified it against its checksum, and ran it on a local page on one Windows machine against four setups: a person, a Scalebrowser profile, and a bare CDP driver with and without Chrome's automation switch. No Reddit page was loaded and no account was used. Each setup ran once, for about 7 minutes, because one check counts five visible minutes.

CheckWhat it readsPersonScalebrowser profileBare CDP driver
h1milliseconds since the page started, when the module registers663333521 to 553
a117 automation markers, including signs that a marker was hiddennonenoneheadless user agent, plus webdriver with the automation switch
e1plugins, PDF viewer, WebGL renderer class, notification permissionfull plugin list, renderer "other"same as personsame as person
r15 navigator values, compared with a fresh hidden iframe5 of 5 same5 of 5 same5 of 5 same
b1battery values and events over 5 visible minutesreadings takensame as personsame as person
c1a console trap that fires when a DevTools client listensnot matchednot matchednot matched
m1pointer path before each click21 clicks, 5 to 65 samples5 clicks, 5 to 10 samplesno click accepted
m2the same, with the geometry of the click target21 clicks5 clicksno click accepted
m3every click, with its wider context23 clicks, 4 without a path6 clicks, 1 without a path4 clicks, 4 without a path
Source: Reddit platform_health block, 18,475 bytes, run verbatim on a local page, Scalebrowser engine 150 and Chrome 152 on one Windows machine, 1 run per setup, 8 September 2026

Three results carry the case. The bare driver was caught on markers in a1 and on input in m1 to m3: none of its 4 clicks had a single pointer sample before it. The Scalebrowser profile raised no marker, and 5 of its 6 clicks came with a path of 5 to 10 samples.

The one click without a full path was a second click on the same spot, where no pointer moves in between. It still carried 2 samples, where the bare driver's carried 0. The person produced 4 such clicks out of 23, so this is a pattern of people rather than of drivers. What does separate our clicks from the person's is the spread: 5 to 10 samples against 5 to 65. Every single value lies within the human range, and whether Reddit's server scores the narrower spread is open; this bench cannot see the server.

c1 teaches the most about the bench itself. The bare driver had the protocol's Runtime domain enabled and was receiving console events, and the trap still did not fire in Chrome 152. A clean "not matched" for your own browser there says nothing about your own browser, which is why a bench needs a positive control before any clean result counts.

Is navigator.webdriver still the main signal?

No. navigator.webdriver is one of 17 markers in one of 9 checks, and 5 of the 17 look for traces of hiding: a deleted flag, an altered property, a plugin list or permission object with the wrong shape, and client hints that disagree with the user agent. A driver that only removes the flag has swapped one marker for another. The grid that hardwareConcurrency and deviceMemory values must sit on is covered in hardwareConcurrency and deviceMemory. The rounding of navigator.connection values is covered in navigator.connection.

The larger signal sits below the page. Ian L. Paterson ran 7 tools against 31 targets, 651 verdicts over 3 sweeps, and concluded that "Playwright forks fail regardless of patch quality". In his words: "A fingerprint-patch tool can rewrite navigator properties all day without touching this layer." The only tool with no blocked target drove Chrome over CDP directly. That is the layer how sites detect bots calls the control plane, and it sits between the connection and the input. The signals that give a proxy exit away are covered in Proxy detection.

What does the Chrome DevTools Protocol expose?

The Chrome DevTools Protocol exposes nothing to the page directly; the page sees what a driver does with it. A tab that is attached but not in front reports visibilityState "hidden", renders at 0 frames per second and swallows input while the driver is told the click was dispatched, and real Chrome behaves the same way. A tab the driver creates arrives without a Referer header and with Sec-Fetch-Site: none, unlike a tab a person opens from a link. The Chrome DevTools Protocol article covers these one by one, and the CDP page of the documentation describes the connection a Scalebrowser profile offers.

Which stealth tools act on this layer?

Patchright and rebrowser patch Playwright's protocol leaks, and nodriver drops the Playwright layer altogether; in Paterson's benchmark rebrowser-playwright was blocked on the same targets as unpatched Playwright. The comparison of stealth tools for automation sets all seven side by side.

Run it on your own machine

Seven days to try it with your own agents on your own sites. Starting the trial needs a card.

Written by

Davide Grasböck

Founder, Scalebrowser

Builds Scalebrowser, the browser layer for AI agents that runs on your own machine. Measures every change a web page could observe against a real browser before it ships, and writes up the ones that turned out wrong.

All articles by Davide Grasböck