Automation & headless detection
WebDriver flags, driver traces, attached DevTools clients, patched built-ins and other signals that reveal a browser is automated or headless.
What to do about it
Driver traces
Launch Chromium with --disable-blink-features=AutomationControlled, or better, drive the browser over CDP without WebDriver. Stealth plugins hide cdc_ keys but leave patched built-ins.
Patched built-ins
JavaScript-level spoofing is always visible: toString, own properties, prototype diffs, cross-realm checks. Spoof at the engine level (browser build or flags), not with injected scripts.
Headless window
Give the browser a real window with toolbar and borders, a plausible size, and let something interact with the page before it matters: user activation gates many APIs.
DevTools
An attached CDP client with the Runtime domain enabled is detectable through console serialisation. Detach before visiting sensitive sites, or avoid enabling Runtime.
How this test works
The page inspects navigator.webdriver here and inside a Worker, scans window for driver globals, compares the source text of built-in functions with the native form using both the page’s toString and a fresh iframe’s, lists own properties on navigator and screen, diffs Navigator.prototype against a clean realm, baits a CDP client with a console getter, reads Error.stack for injected frames, and checks window geometry, plugins, permissions and user activation. Extensions are detected through the globals, DOM markers and resources they inject.