← Glossary / Playwright Stealth

What is Playwright Stealth?

Playwright Stealth is a collection of evasion scripts designed to mask the default automation signatures of the Playwright browser framework. It patches obvious leaks like navigator.webdriver, mocks missing plugins, and overrides permissions to make headless Chromium look like a standard consumer browser. While effective against basic checks, relying on stealth plugins against enterprise anti-bot stacks is a losing game of whack-a-mole that ultimately ends in pipeline failure.

Headless EvasionBrowser FingerprintingAutomationChromiumAnti-Bot
// 02 — definitions

Patching the
leaks.

How automation frameworks try to hide their tracks, and why surface-level JavaScript patching isn't enough for production data pipelines.

Ask a DataFlirt engineer →

TL;DR

Playwright Stealth injects evasion scripts into the browser context before the target page loads. It overrides properties that scream "bot" — like the webdriver flag, headless user agents, and missing language packs. It works well for simple scrapers, but modern WAFs like Cloudflare and DataDome look deeper at TLS handshakes, canvas rendering, and execution timing, rendering JS-level stealth obsolete.

01Definition & structure
Playwright Stealth is a community-maintained set of scripts that modify the JavaScript environment of a Playwright-controlled browser. By default, headless Chromium exposes several properties (like navigator.webdriver = true) that immediately flag it as a bot. Stealth plugins use page.addInitScript() to inject overrides before the target website's code executes, attempting to spoof a legitimate user environment.
02How it works in practice
The plugin intercepts calls to native browser APIs using JavaScript Proxies. If a site asks for the browser's plugin list, the stealth script intercepts the request and returns a hardcoded array of fake plugins. If a site checks the WebGL renderer, it returns a spoofed graphics card string instead of "Google SwiftShader".
03The proxy trap vulnerability
Modern anti-bot systems defeat stealth plugins by detecting the JavaScript Proxies themselves. They do this via timing attacks (native C++ getters are micro-seconds faster than JS proxies) or by inspecting the toString() representation of the functions, which often leak that they have been overridden. Once a proxy is detected, the bot score goes to 1.0.
04How DataFlirt handles it
We abandon the stealth plugin approach entirely. Instead of trying to patch a headless browser to look real, we run actual headed browsers on our infrastructure. Because the browser is genuinely rendering a display and executing native APIs without proxies, there are no JS traps for a WAF to detect. This guarantees long-term pipeline stability.
05Did you know?
Most stealth plugins for Playwright are actually direct ports of the older puppeteer-extra-plugin-stealth. Because the evasion techniques are open-source and widely used, anti-bot vendors use the stealth repositories as a roadmap for exactly what to detect in their next update.
// 03 — the detection math

Why JS patches
fail at scale.

Anti-bot vendors don't just check if a property exists; they measure the execution time of the getter. Proxying native browser properties via JavaScript introduces measurable latency.

Proxy Latency Detection = Tgetter = tproxy - tnative
If T > 0.05ms, the property is likely mocked via JS. DataDome JS Challenge
Fingerprint Coherence = C = JS_SignalsTLS_SignalsHTTP2_Signals
Stealth patches JS, but leaves TLS/HTTP2 untouched, breaking coherence. Akamai BMP
DataFlirt Evasion Score = E = 1 - (Patched_APIs / Total_APIs)
We aim for E=1 by using real browsers, not patched ones. Internal SLO
// 04 — execution trace

A stealth patch
getting caught.

Trace of a Playwright Stealth instance attempting to bypass a modern JS challenge. The patch works, but the proxy trap is detected.

PlaywrightChromium HeadlessJS Challenge
edge.dataflirt.io — live
CAPTURED
// injecting stealth scripts
page.addInitScript: "webdriver.js"
page.addInitScript: "chrome.app.js"

// executing target challenge
eval: navigator.webdriver
result: undefined // patch successful

eval: Object.getOwnPropertyDescriptor(navigator, 'webdriver')
result: [object Object] // trap detected

eval: navigator.plugins.length
result: 3 // patch successful

eval: performance.now() - start_time
result: 4.2ms // execution too slow for native API

// classifier decision
score.bot: 0.98
action: BLOCK (CAPTCHA served)
// 05 — failure modes

Where stealth
plugins leak.

The most common ways Playwright Stealth instances are detected by enterprise WAFs. JavaScript patching is inherently fragile.

DETECTION RATE ·  ·  ·    >85% on Tier 1 WAFs
MAINTENANCE ·  ·  ·  ·    High overhead
UPDATED ·  ·  ·  ·  ·  ·  2026-05-19
01

Proxy Trap Latency

Timing attacks · Measuring the speed of mocked getters
02

TLS/JS Mismatch

Network layer · JA3 doesn't match the spoofed User-Agent
03

Canvas Fingerprint

Rendering · Headless rendering differs from headed
04

Stack Trace Leaks

Execution · Errors reveal playwright internals
05

Missing APIs

Feature detection · New browser APIs not yet mocked
// 06 — the dataflirt way

Real browsers,

not patched headless instances.

We don't use Playwright Stealth. Patching JavaScript properties is an endless arms race that guarantees pipeline instability. Instead, DataFlirt runs unmodified, headed browsers on real hardware. When your TLS handshake, HTTP/2 framing, and JavaScript execution environment are genuinely coherent, there is nothing to patch and nothing to detect. Authenticity scales better than evasion.

Browser Profile Coherence

Live snapshot of a DataFlirt browser profile bypassing a JS challenge.

engine.mode headed
navigator.webdriver false (native)
tls.ja3_hash matches_chrome_124
js.proxy_traps 0 detected
canvas.renderer hardware_gpu
pipeline.status undetected

Stay ahead of the pipeline

Data engineering
intel, weekly.

Anti-bot shifts, scraping infrastructure updates, dataset delivery patterns, and business outcomes from our pipelines. Short, technical, no fluff.

// 07 — FAQ

Common
questions.

Common questions about Playwright Stealth, detection mechanisms, and why enterprise pipelines abandon it.

Ask us directly →
What exactly does Playwright Stealth do? +
It injects JavaScript into every page before it loads to overwrite properties that indicate automation. This includes removing the `navigator.webdriver` flag, mocking the `navigator.plugins` array, and faking WebGL vendor strings to make a headless browser look like a normal user.
Does it work against Cloudflare or DataDome? +
Only against their most basic configurations. Advanced bot management systems like Cloudflare Turnstile or DataDome use timing attacks to detect the JavaScript proxies that stealth plugins rely on. They also cross-reference JS signals with TLS handshakes, which stealth plugins cannot patch.
Why is my stealth scraper still getting blocked? +
Because JavaScript is only one layer of the fingerprint. If your IP is from an AWS datacenter, or your TLS JA3 hash looks like a Go HTTP client, patching `navigator.webdriver` won't save you. Detection is holistic; stealth plugins are superficial.
How does DataFlirt bypass detection without stealth plugins? +
We use real, headed browsers running on actual hardware, routed through residential ISP networks. We don't need to patch the `webdriver` flag because we don't trigger it. By maintaining absolute coherence across the network, TLS, and JS layers, we avoid detection entirely.
Is Playwright Stealth better than Puppeteer Stealth? +
They are functionally identical and share the same underlying evasion techniques (often ported directly from the puppeteer-extra-plugin-stealth repository). Neither is sufficient for enterprise-grade scraping against modern WAFs.
Can I use stealth plugins for high-volume scraping? +
You can, but you will spend more engineering hours updating patches than extracting data. Every time a browser updates or a WAF deploys a new challenge, your stealth scripts will break. It is not a viable strategy for pipelines with strict SLAs.
$ dataflirt scope --new-project --target=playwright-stealth READY

Tell us what
to extract.
We do the rest.

20-minute scoping call. Pilot dataset within the week. Production within two. Whether you need a one-off catalogue dump or a continuous feed across millions of records — we scope, build, and operate the pipeline.

hello@dataflirt.com  ·  Bengaluru  ·  IST  ·  typical reply < 4h