
Headless Browser Attacks: Detecting Puppeteer, Playwright, and Stealth Plugins
From Testing Tools to Attack Weapons
Browser automation frameworks like Puppeteer, Playwright, and Selenium were originally designed to help developers test web applications automatically. But the very capabilities that make them excellent testing tools — full browser control, JavaScript execution, and user interaction simulation — have also made them the weapons of choice for attackers.
These tools are used today in a wide range of attacks: from web scraping and credential stuffing, to mass fake account creation and automated purchasing of limited-edition products (scalping). The Imperva Bad Bot Report 2025 indicates that over 30% of advanced bot traffic uses headless browsers.
Headless Browser Architecture: How It Works
A "headless" browser is a complete web browser that runs without a visible graphical interface. The attacker controls it programmatically through the Chrome DevTools Protocol (CDP) or WebDriver protocol, enabling execution of any action a human user could perform: navigating pages, filling forms, clicking buttons, and even capturing screenshots.
The danger lies in the fact that a headless browser executes JavaScript fully, loads CSS, and builds the DOM tree exactly like a regular browser. This means simple JavaScript-based checks (such as verifying the existence of certain DOM elements) may fail to detect it.
Stealth Plugins: The Camouflage Arms Race
As headless browser detection techniques evolved, stealth plugins emerged specifically designed to hide automation traces. The most prominent are puppeteer-extra-plugin-stealth and playwright-stealth. These plugins perform a series of modifications to hide automated operation:
Removing navigator.webdriver: The property automatically set by the browser when operated via WebDriver.
Spoofing navigator.plugins: Adding fake plugins (like Chrome PDF Plugin) to simulate a regular browser.
Modifying WebGL and Canvas results: To prevent detection that the server GPU differs from a typical user's computer GPU.
Hiding Chrome-specific properties: Such as window.chrome and Permissions API to appear as a regular Chrome browser.
However, these very modifications leave traces that can be detected, as we will see in the next section.
Advanced Detection Methods: Beyond the WebDriver Check
CDP Detection
The Chrome DevTools Protocol (CDP) is the mechanism through which Puppeteer and Playwright control the browser. Even with stealth plugins, CDP leaves traces that are difficult to hide. For example, when CDP is used to inject JavaScript before page load (via Page.addScriptToEvaluateOnNewDocument), this can be detected by examining script execution order and timing.
Additionally, certain CDP functions like Runtime.enable and Network.enable activate additional event listeners in the browser that can be detected from within the web page through performance measurement and operation timing.
Prototype Tampering Detection
Stealth plugins typically work by modifying properties of built-in JavaScript objects (such as navigator and window). But these modifications leave fingerprints detectable through prototype chain inspection. For example:
Checking toString() of modified functions — native functions return "[native code]" while modified functions may not do so correctly.
Examining Object.getOwnPropertyDescriptor() — reveals whether properties are native or redefined.
Proxy detection — some stealth plugins use JavaScript Proxy objects to intercept property access, detectable through specific tests.
Isolated iframe Inspection
An effective detection technique relies on creating an iframe with an isolated context and inspecting its objects. Stealth plugins typically modify the main page context but may fail to modify new iframe contexts. Comparing navigator and window properties between the main context and the isolated iframe context can reveal inconsistencies caused by stealth plugins.
TLS Fingerprinting: Detection Before JavaScript Loads
All previous detection methods operate after the web page loads and JavaScript executes. But what if you could detect the bot before any code loads? This is where TLS fingerprinting comes in.
When establishing an HTTPS connection, the browser sends a "Client Hello" message containing detailed technical information: supported TLS versions, cipher suites, elliptic curves, and extensions. This information forms a unique fingerprint known as the JA3/JA4 fingerprint.
Real browsers (Chrome, Firefox, Safari) have distinctive and well-known TLS fingerprints. Headless browsers, even with stealth plugins, often produce different TLS fingerprints because they use modified versions of the browser engine or connect through different HTTP libraries.
Systems like gkcaptcha use TLS fingerprinting as the first detection layer. If the TLS fingerprint does not match any known browser, the suspicion level is raised immediately — before any JavaScript code reaches the browser. This layer is particularly effective because modifying TLS fingerprints requires changes at the TLS library level itself, which is far more difficult than modifying JavaScript properties.
Cross-Fingerprint Validation: Catching Anti-Detect Browsers
A new category of tools called anti-detect browsers — such as Multilogin, GoLogin, and AdsPower — has emerged. These browsers allow attackers to create multiple browser profiles with unique identities, each featuring different Canvas, WebGL, font, and screen fingerprints.
To detect these browsers, cross-fingerprint validation is employed. The concept is straightforward: in a real browser, all fingerprints are internally consistent. A browser claiming to be Chrome 120 on Windows 11 should have a TLS fingerprint matching Chrome 120, a WebGL fingerprint matching a GPU that actually exists in known hardware, and a screen resolution matching real devices.
Anti-detect browsers often fail to maintain this internal consistency. For instance, they may show a WebGL fingerprint for a graphics card incompatible with the declared operating system, or a TLS fingerprint that does not match the claimed browser version.
The WebDriver Flag and Beyond
The navigator.webdriver flag is the simplest detection method and the easiest to bypass. Browsers set this flag to true automatically when operated via the WebDriver protocol. Stealth plugins delete it or set it to false.
But advanced detection goes beyond directly checking this flag — it looks for side effects. Even after removing navigator.webdriver, traces may remain in:
Environment variables: Such as CDPSession and the presence of debugging objects in memory.
Window properties: Headless window dimensions differ from regular browsers (e.g., outerWidth === innerWidth in headless browsers).
Performance behavior: The Performance API shows different timings in headless browsers compared to regular ones.
Building a Multi-Layered Defense
No single detection method is sufficient on its own. Effective defense relies on stacking multiple detection layers, where the bot must bypass all of them simultaneously:
Layer 1 — TLS fingerprinting (JA3/JA4): Detection before any code loads. Effective against simple libraries and unmodified headless browsers.
Layer 2 — Environment checks: WebDriver detection, CDP detection, prototype tampering, isolated iframe inspection. Effective against basic stealth plugins.
Layer 3 — Cross-fingerprint validation: Detecting inconsistencies between TLS fingerprint, browser fingerprint, WebGL, and fonts. Effective against anti-detect browsers.
Layer 4 — Behavioral analysis: Mouse movement analysis and keystroke dynamics. Effective against the most sophisticated bots that bypass all environmental checks.
Conclusion: There Is No Silver Bullet
The arms race between bot developers and detection systems is continuous and will not stop. Every new detection method developed, bot developers find ways to circumvent. But effective defense does not rely on a single "impenetrable" check — it relies on the accumulation of dozens of cross-validated checks that the bot must bypass simultaneously.
Bypassing one check is easy. Bypassing ten checks is possible. Bypassing a hundred internally consistent checks simultaneously — that is what makes effective detection achievable.
Saudi organizations facing increasing threats from advanced bots need multi-layered detection solutions that combine network-level analysis (TLS fingerprinting), browser-level analysis (environment checks and fingerprints), and user-level analysis (behavioral biometrics). Relying on a single layer means the next advanced bot will bypass it.