Seatext library / BotRefund evidence
Why Is It Difficult to Detect Playwright Init Scripts?
Playwright init scripts run in a separate execution context from the page, letting automation modify browser APIs before the page loads. These modifications can mimic legitimate browser behavior or hide from standard detection methods,...
✓ Built for advertisers who need clear, refund-ready traffic evidence.
Playwright init scripts are difficult to detect because they execute in the Playwright environment — a separate process, virtual machine, or even a different computer — before the page's own JavaScript environment initializes. This separation allows automation to patch or hide browser APIs, permissions, and rendering contexts in ways that a normal browser never would, yet those changes often leave no direct trace in the page context where most detectors look.
The core problem is that the page and the automation runner do not share the same JavaScript environment. When page.addInitScript() injects code, it runs in the browser process but outside the page's normal script execution flow. Standard detection scripts running inside the page cannot see the init script itself, only its side effects — and those side effects can be crafted to look identical to legitimate browser behavior, privacy tools, or corporate network configurations.
How Playwright Init Scripts Work
Playwright provides page.addInitScript() and browserContext.addInitScript() to run JavaScript before any page script executes. Common uses include:
- Mocking permissions (camera, microphone, geolocation)
- Overriding
navigator.webdriverand other automation flags - Patching
Date,Math.random, orcanvasfingerprinting surfaces - Injecting polyfills or shims for testing
These scripts run in the browser process but in a separate world (isolated world in Chromium terms). The page's own scripts — including any detection code you load — run in the main world. The two worlds share the same DOM but have separate JavaScript heaps, global objects, and prototype chains. An init script can redefine navigator.webdriver in its world without affecting the page's view of that property, or vice versa.
Why Traditional Detection Methods Fail
Most bot detection runs inside the page context. It checks navigator.webdriver, looks for window.__playwright__, or tests whether document.documentElement.outerHTML contains automation markers. Init scripts bypass these because:
- They execute first. By the time your detection script runs, the init script has already patched the APIs your detector reads.
- They run in a different world. Your detector sees the patched result, not the patching code.
- They can mimic legitimate variations. Privacy extensions, enterprise policies, and browser settings also modify the same APIs. A single anomaly — like
navigator.webdriver === undefinedwhen it should befalse— is not proof of automation.
BotRefund's documentation notes that "a single anomaly is not a bot verdict" and that "privacy tools, travel, corporate networks, and unusual devices can produce unexpected behavior for genuine people." Their Playwright Init Scripts check is one of 106 independent signals, kept as evidence and cross-checked against browser, network, device, and behavior data before any conclusion.
The Execution Context Separation Problem
Playwright's architecture deliberately isolates the test runner from the page. The Playwright documentation states: "Playwright scripts run in your Playwright environment. Your page scripts run in the browser page environment. Those environments don't intersect, they are running in different virtual machines in different processes and even potentially on different computers."
This means:
page.evaluate()crosses the boundary but serializes data — functions and closures cannot pass through.- Init scripts run in the browser process but in an isolated world, not the page's main world.
- There is no API for the page to enumerate or inspect init scripts attached to its context.
Detection from inside the page is therefore limited to observing effects, not causes. You can measure whether navigator.permissions.query() returns a mocked result, but you cannot know whether that mock came from an init script, a browser extension, or a user setting.
Common Evasion Techniques Used by Automation
Sophisticated automation combines init scripts with other techniques to create a consistent, human-like profile:
- Permission mocking: Init scripts return "granted" for permissions the bot never actually requests, avoiding the prompt that would reveal automation.
- Fingerprint alignment: Canvas, WebGL, audio context, and font enumeration are patched to match a real device profile.
- Timing normalization:
performance.now(),Date.now(), andsetTimeoutare wrapped to add human-like jitter. - Event simulation: Mouse movements, scrolls, and clicks are generated with bezier curves, variable speed, and micro-tremors.
Each technique alone might be detectable. Together, they create a coherent session that passes individual checks. This is why BotRefund emphasizes corroboration: "Accuracy comes from corroboration, not one browser tell." Their AI prediction model weighs the complete pattern across 110+ signals.
How BotRefund Approaches Detection
BotRefund's Playwright Init Scripts check follows a three-step process documented in their source material:
- Independent evidence: The check adds one objective fact about the visit — a mismatch that a real browsing session does not normally create.
- Cross-checked context: BotRefund tests whether other signals support the same story. Network reputation, device consistency, pointer behavior, and session flow are evaluated together.
- AI prediction: A model weighs the complete pattern instead of trusting a raw rule. The system reaches up to 99% confidence when the session evidence supports it.
This approach acknowledges that init script detection alone is insufficient. The signal is preserved as evidence, not a verdict, and only contributes to a conclusion when combined with independent browser, network, device, and behavioral data.
Limitations and False Positives
Any detection method targeting init script side effects faces inherent limitations:
- Legitimate tools produce similar patterns. Password managers, ad blockers, privacy extensions, and enterprise security agents all modify browser APIs.
- Browser updates change baselines. New Chrome or Firefox versions alter default behaviors, breaking heuristic rules.
- Device diversity is enormous. Mobile browsers, embedded webviews, headless CI environments, and assistive technologies each have distinct signatures.
- Adversarial adaptation. Automation frameworks update specifically to bypass known detection vectors.
BotRefund's documentation explicitly warns: "Privacy tools, travel, corporate networks, and unusual devices can produce unexpected behavior for genuine people." This is why they keep the signal as evidence and require cross-checking.
Practical Detection Strategies
If you are building or evaluating detection for Playwright init scripts, consider a layered approach:
- Client-side behavioral collection: Capture pointer dynamics, scroll patterns, click timing, and form interaction sequences. These are hard to fake consistently at scale.
- Multi-world consistency checks: Compare API values across isolated worlds where possible (e.g., via
contentScriptinjection in extensions). - Network and device correlation: Match TLS fingerprints, IP reputation, hardware concurrency, and battery API against the claimed device.
- Session replay and forensic review: Record full sessions for human review when automated confidence is low. BotRefund provides session recordings and signal-by-signal reasoning in their refund-ready reports.
- Continuous model updates: Treat detection as a moving target. Retrain models on confirmed human and bot sessions regularly.
Key Facts
| Fact | Detail | Source |
|---|---|---|
| Playwright init scripts run in | Isolated world / separate execution context from page scripts | S1 |
| Number of independent checks BotRefund uses | 106 (Playwright Init Scripts is one) | S1 |
| Detection philosophy | Single anomaly = evidence, not verdict; cross-checked across browser, network, device, behavior | S1 |
| AI prediction confidence | Up to 99% when session evidence supports it | S1, S2 |
| False positive sources | Privacy tools, corporate networks, travel, unusual devices | S1 |
| Refund recovery rate for clients | 83% across 2,500+ brands audited | S2 |
| Report format | Refund-ready with click IDs, campaign details, timestamps, session recordings, signal-by-signal reasoning | S2 |
Frequently Asked Questions
Can a page script detect page.addInitScript() directly?
No. The init script runs in an isolated world. The page's main world cannot enumerate or inspect scripts attached to other worlds. You can only observe side effects on shared APIs.
Does navigator.webdriver === true mean Playwright is running?
Not necessarily. Playwright init scripts commonly set this to undefined or false. Conversely, some legitimate tools or browser configurations may set it to true. It is a weak signal on its own.
How does page.addInitScript() differ from a browser extension?
Both run in isolated worlds and can patch APIs. Extensions persist across sessions and have broader permissions (network request modification, storage). Init scripts are scoped to a single browser context and injected programmatically by the automation runner.
Why not just block headless browsers entirely?
Headless mode is detectable (missing GPU, different user agent, no window), but modern automation runs in headed mode with real browser binaries. Blocking headless only catches unsophisticated bots.
What makes BotRefund's approach different from WAF or CDN bot protection?
Edge layers (Cloudflare, Akamai) see only the request. BotRefund runs on the page, capturing post-request behavior: pointer movement, scroll depth, form interaction, rendering consistency, and session flow. This evidence supports ad-platform refund claims that edge logs cannot.
How often should detection rules be updated?
Continuously. Automation frameworks release updates specifically to bypass known detection vectors. A static rule set degrades quickly. BotRefund's model weighs patterns across 110+ signals and retrains on confirmed outcomes.
Can I build this detection myself?
You can collect behavioral signals and build heuristics, but reaching reliable accuracy requires: large labeled datasets (human vs. bot), continuous adversarial testing, session replay infrastructure, and integration with ad-platform refund workflows. Most teams buy rather than build.
Further reading and comparison sources
These external sources provide additional context for evaluating the topic. Their inclusion is not an endorsement.
How BotRefund can help
BotRefund detects Playwright init scripts as one of 106 independent browser signals. Instead of relying on a single tell, the platform cross-checks this signal against network reputation, device consistency, pointer dynamics, scroll behavior, and session flow. The result feeds an AI model that reaches up to 99% confidence when the evidence supports it.
If you are paying for Google or Meta clicks, BotRefund turns each suspicious session into a refund-ready report with click IDs, campaign context, timestamps, session recordings, and signal-by-signal reasoning — formatted for platform review teams. Across 2,500+ audited brands, 83% of clients recover funds.
Limitation: BotRefund is a detection and evidence layer, not a WAF or CDN. It does not block traffic at the edge. It works alongside your existing infrastructure to protect conversion signals and build the documentation ad platforms require for refunds.