CloakBrowser Source-Level Patches vs Playwright-Stealth JS Injection: What’s the Difference?
CloakBrowser modifies Chromium at the C++ source level with 49 compiled patches that become part of the browser binary, while Playwright-Stealth relies on runtime JavaScript injection to overwrite browser properties, making CloakBrowser’s approach significantly harder to detect and more stable across Chrome versions.
CloakBrowser and Playwright-Stealth both aim to mask automated browser detection, but they operate at fundamentally different layers of the stack. While Playwright-Stealth patches globals like navigator.webdriver via injected scripts, CloakBrowser ships a custom Chromium binary where fingerprint-related signals are altered before the browser ever starts. Understanding these architectural differences is critical for developers building automation pipelines that must evade sophisticated anti-bot systems.
Implementation Layer: Compiled Binary vs Runtime Scripts
CloakBrowser’s C++ Source Patches
CloakBrowser applies 49 source-level C++ patches directly inside Chromium’s source code at the repository level, as noted in the README.md. These patches modify how the browser handles canvas, WebGL, audio, GPU, screen size, WebRTC, and network timing at the native level. Because the changes are compiled into the binary that ships with the library, the browser behaves exactly like a standard Chrome instance with no "patched" flags visible to JavaScript detection tools running on the page.
According to the CHANGELOG.md, these patches are rebased on every Chromium update (documented transitions like "145 → 146"), ensuring compatibility with new Chrome releases without breaking the stealth mechanisms. Since the modifications live in the compiled binary, there is zero runtime overhead for script injection and no risk of race conditions between page load and patch application.
Playwright-Stealth’s JavaScript Injection
Playwright-Stealth operates on a stock Chromium binary and injects stealth logic via JavaScript using addInitScript or evaluate calls. The library monkey-patches global objects such as window.navigator, HTMLCanvasElement, and navigator.plugins after the page loads. This approach leaves detectable traces, including global variables like window.__playwright_stealth__ or anomalies in the [[Prototype]] chain that anti-bot services can query.
Because Playwright-Stealth relies on overwriting properties at runtime, it faces significant fragility: a new Chrome version can change an internal property name, causing the injected script to break or become detectable. Additionally, Content Security Policy (CSP) headers that block eval or addInitScript can prevent the stealth scripts from executing entirely, and the injection process adds measurable delays that sophisticated detection systems can flag.
The Stealth World: Architecture Without JavaScript Injection
Isolated CDP World Implementation
Rather than injecting JavaScript into the page context, CloakBrowser creates an isolated Chrome DevTools Protocol (CDP) world that operates outside the page’s JavaScript environment. In cloakbrowser/human/__init__.py, the patch_page function (lines 27-35) instantiates a _SyncIsolatedWorld object and attaches it to page._stealth_world:
# cloakbrowser/human/__init__.py
def patch_page(page: Any, cfg: HumanConfig, cursor: _CursorState) -> None:
...
# --- Stealth infrastructure ---
try:
stealth = _SyncIsolatedWorld(page) # Creates isolated CDP world
page._stealth_world = stealth
cdp_session = stealth.get_cdp_session()
except Exception:
stealth = None
page._stealth_world = None
This isolated world maintains its own global objects and CDP session, allowing CloakBrowser to send commands without polluting the page’s window object or leaving JavaScript traces. Because no scripts are injected into the main world, detection tools cannot find overwritten property descriptors or injected code blocks.
Trusted Input Events via CDP
CloakBrowser generates human-like mouse and keyboard events through CDP Input.dispatchKeyEvent commands rather than JavaScript KeyboardEvent constructors. The implementation in cloakbrowser/human/keyboard.py (lines 130-155) dispatches these events directly to the browser’s input handling layer:
# Simplified from cloakbrowser/human/keyboard.py
cdp_session.send("Input.dispatchKeyEvent", {
"type": "keyDown",
"key": character,
"modifiers": modifiers,
"text": text,
"isTrusted": True
})
Events dispatched via CDP carry the trusted flag (isTrusted = true) and do not produce synthetic stack traces, eliminating a common detection vector used to identify Selenium or Playwright automation. This occurs entirely outside the page’s JavaScript execution context, ensuring the main world remains untouched and undetectable.
Stability and Detection Considerations
Version Compatibility and Maintenance
CloakBrowser’s source-level approach requires rebasing the 49 C++ patches against each new Chromium release, which the maintainers document in CHANGELOG.md. This upfront investment ensures that fingerprinting signals remain consistent with real Chrome behavior across versions. In contrast, Playwright-Stealth’s JavaScript patches are reactive: when Chrome updates change internal APIs or property structures, the monkey-patching scripts may fail silently or begin throwing detectable errors.
Detection Surface and Security Risks
CloakBrowser’s architecture presents a minimal detection surface because no JavaScript code is added to the page. The only "stealth" component is the isolated CDP world, which remains invisible to page-side JavaScript inspection. Playwright-Stealth, by necessity, must add scripts to every browsing context, creating forensic evidence that sophisticated anti-bot systems can fingerprint. Additionally, runtime injection is vulnerable to CSP restrictions and timing attacks where detection scripts execute before the stealth patches apply.
Practical Implementation Examples
Launching a Stealth Browser with CloakBrowser
CloakBrowser functions as a drop-in replacement for Playwright that requires no extra configuration to enable stealth:
from cloakbrowser import launch
browser = launch() # Downloads the patched Chromium binary
page = browser.new_page()
page.goto("https://protected-site.com") # Passes Cloudflare, reCAPTCHA, etc.
browser.close()
All stealth capabilities originate from the modified binary itself; no additional flags or script injection calls are required.
Enabling Human-Like Input
To activate the isolated-world input system, pass humanize=True when launching:
browser = launch(humanize=True) # Activates isolated-world input patching
page = browser.new_page()
page.click("button#login") # Executed via CDP Input.dispatchKeyEvent
page.type("#email", "user@example.com") # Typed with realistic delays
The HumanConfig object manages timing distributions, while the actual event dispatching leverages the CDP infrastructure defined in cloakbrowser/human/__init__.py.
Comparison with Playwright-Stealth Setup
Playwright-Stealth requires explicit initialization and script injection for each page context:
const { chromium } = require('playwright');
const playwrightStealth = require('playwright-stealth');
(async () => {
const browser = await chromium.launch({ headless: false });
const context = await browser.newContext();
const page = await context.newPage();
await playwrightStealth(page); // Injects stealth JavaScript bundle
await page.goto('https://protected-site.com');
})();
This playwrightStealth(page) call injects JavaScript that rewrites Object.defineProperty descriptors for navigator.webdriver and other fingerprinting APIs, leaving the modifications visible to any script running on the target page.
Key Source Files and Implementation Details
cloakbrowser/human/__init__.py— Contains thepatch_pagefunction (lines 27-35) that creates_SyncIsolatedWorldand wires the stealth infrastructure to the page object.cloakbrowser/human/keyboard.py— ImplementsInput.dispatchKeyEventcalls (lines 130-155) that generate trusted input events without JavaScript execution.README.md— Documents the 49 source-level C++ patches and explains why compiled patches outperform config-level JavaScript hacks.CHANGELOG.md— Tracks the rebasing of patches across Chromium versions (e.g., "145 → 146"), demonstrating ongoing maintenance of the binary patches.tests/test_stealth_unit.py— Unit tests verifying that the isolated world attaches correctly and CDP calls dispatch as expected.
Summary
- CloakBrowser applies 49 C++ patches at the source level, compiling stealth directly into the Chromium binary with no JavaScript injected into pages.
- Playwright-Stealth depends on runtime JavaScript injection to monkey-patch browser globals, leaving detectable traces and vulnerable to CSP blocks.
- CloakBrowser uses an isolated CDP world (
_SyncIsolatedWorld) to handle trusted input events viaInput.dispatchKeyEvent, eliminating synthetic event signatures. - Source-level patches are rebased for every Chromium update, ensuring stability, while JavaScript injection methods break when internal Chrome APIs change.
- CloakBrowser requires zero runtime configuration for stealth, whereas Playwright-Stealth needs manual script injection per page context.
Frequently Asked Questions
What makes source-level patches harder to detect than JavaScript injection?
Source-level patches modify Chromium’s native behavior before compilation, meaning the browser inherently reports authentic fingerprint data without executing JavaScript overrides. Since CloakBrowser never injects scripts into the page’s main world, anti-bot systems cannot detect overwritten property descriptors or injected global variables that typically signal automation frameworks.
Does CloakBrowser require manual Chromium compilation?
No. CloakBrowser ships pre-compiled patched binaries that download automatically when you call launch(). The CloakHQ team handles the complex process of rebasing the 49 C++ patches against each new Chromium release, as documented in CHANGELOG.md, so users receive a stable binary without managing source code themselves.
Can websites detect CloakBrowser’s isolated CDP world?
The isolated CDP world operates in a separate JavaScript context from the main page, meaning window object inspection and prototype chain analysis from the site’s perspective reveal no modifications. Since input events originate from CDP Input.dispatchKeyEvent rather than JavaScript event constructors, they carry authentic trusted flags that match genuine user interactions, making detection via event forensics extremely difficult.
How does CloakBrowser handle Chrome version updates differently from Playwright-Stealth?
CloakBrowser updates involve rebasing the 49 C++ source patches onto the latest Chromium codebase, then compiling a new binary—ensuring fingerprint consistency with the target Chrome version. Playwright-Stealth relies on JavaScript property names remaining stable across Chrome releases; when Google changes internal APIs or adds new anti-automation checks, the JavaScript patches may fail or become obsolete until the community updates the monkey-patching code.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →