How C++ Patches in CloakBrowser Remove Automation Signals: navigator.webdriver and chrome
CloakBrowser eliminates automation detection by applying 49 C++ source-level patches to the Chromium build process, hardcoding navigator.webdriver to false and ensuring window.chrome mirrors a genuine Chrome installation, effectively bypassing the --enable-automation flag at the binary level.
CloakBrowser from CloakHQ/CloakBrowser achieves true stealth not through runtime configuration but by modifying the Chromium source code before compilation. These C++ patches target the Blink rendering engine directly, ensuring that automation signals are stripped from the resulting binary and cannot be detected by anti-bot scripts.
Why Source-Level Patches Outperform Runtime Flags
Traditional automation tools rely on launch flags like --enable-automation, which immediately set navigator.webdriver to true and expose the browser as automated. According to the CloakBrowser source code, the wrapper intentionally omits this flag entirely, as noted in cloakbrowser/config.py at lines 30-31. Instead, the project applies a series of binary patches—specifically patch 009—that rewrite the C++ implementations of automation-detection APIs at the source level.
This strategy provides three critical advantages:
- No runtime leakage: Because the changes are baked into the compiled binary, there are no flags to accidentally expose during launch.
- JavaScript independence: The patches operate inside the Blink engine itself, so they survive Playwright or Puppeteer updates and cannot be bypassed by page scripts.
- CDP consistency: Even when controlled via the Chrome DevTools Protocol, the browser returns patched values directly from its core C++ implementation.
How navigator.webdriver Is Hardcoded to False
The most prominent automation signal, navigator.webdriver, is neutralized through a specific binary patch applied during the build process. As documented in CHANGELOG.md at line 58, patch 009 rewrites the getter for navigator.webdriver in the Blink runtime to always return false.
This modification occurs at the C++ level, meaning the property is indistinguishable from a standard Chrome installation. The README.md (lines 73-77) confirms that CloakBrowser uses 49 source-level C++ patches specifically targeting automation signals. By hardcoding the return value rather than filtering it through JavaScript, the patch ensures that detection scripts cannot identify the automation framework regardless of execution context.
Restoring window.chrome to Match Genuine Chrome
Headless or automated Chromium instances typically expose window.chrome as undefined, a clear fingerprint for bot detection. CloakBrowser addresses this by patching the Blink object that exposes window.chrome, ensuring the property exists as a proper object that mirrors the real Chrome API.
As shown in README.md (lines 173-176), the patched browser reports window.chrome as an object rather than undefined, removing the classic "headless-Chrome" fingerprint. This change is implemented directly in the C++ source, meaning the property behaves identically to a standard Chrome browser even when inspected via native code.
Build Process and Verification
The CloakBrowser build system fetches upstream Chromium source code and applies sequentially numbered patch files (patch-001.patch, patch-002.patch, etc.) before compilation. While the exact C++ diff files reside in the build-time patch directory and are not exposed in the public repository, the effects are verified through comprehensive test suites.
Python Verification
The test suite in tests/test_stealth.py (lines 36-38) explicitly asserts that navigator.webdriver returns false:
from cloakbrowser import launch
browser = launch()
page = browser.new_page()
page.goto("https://example.com")
# Verified in tests/test_stealth.py
assert page.evaluate("navigator.webdriver") is False
assert page.evaluate("window.chrome") is not None
browser.close()
JavaScript Verification
Similarly, tests/test_launch.py (lines 44-49) validates these properties immediately after launch:
// This mirrors the verification in tests/test_launch.py
const result = await page.evaluate(() => {
return {
webdriver: navigator.webdriver,
hasChrome: !!window.chrome
};
});
// Assertions confirm webdriver is false and chrome object exists
These tests demonstrate that the compiled binary presents the patched values consistently, even when driven via CDP or standard automation protocols.
Summary
- C++ source patches modify Chromium before compilation, targeting the Blink engine directly.
- Patch 009 specifically hardcodes
navigator.webdrivertofalsein the C++ getter implementation. window.chromeis restored as a proper object matching genuine Chrome behavior, eliminating headless fingerprints.- No
--enable-automationflag is passed, preventing the runtime exposure of automation signals. - Test coverage in
tests/test_stealth.pyandtests/test_launch.pyverifies the patches work across launches.
Frequently Asked Questions
What is the difference between C++ patches and JavaScript stealth scripts?
C++ patches modify the browser's compiled binary at the source level, altering how the Blink engine reports properties like navigator.webdriver. JavaScript stealth scripts attempt to overwrite these properties at runtime, which detection scripts can identify by checking property descriptors or timing attacks. The C++ approach is undetectable because the values originate from the browser's core implementation.
Does CloakBrowser still use the Chrome DevTools Protocol (CDP)?
Yes, CloakBrowser remains compatible with CDP-based tools like Playwright and Puppeteer. However, because the automation signals are removed at the C++ level within the Chromium binary, the patched values persist regardless of how the browser is controlled, whether through CDP or manual interaction.
How can I verify that automation signals are actually removed?
You can run the test suites provided in the repository. Specifically, tests/test_stealth.py asserts that navigator.webdriver is false and tests/test_launch.py verifies this immediately after browser launch. Alternatively, evaluate navigator.webdriver and window.chrome in any page console—the former should return false and the latter should return a defined object.
Where are the actual C++ patch files located?
The specific C++ diff files (such as patch-009.patch) are applied during the build process and reside in the build-time patch directory, not in the public source repository. However, their effects and implementation details are documented in CHANGELOG.md and README.md, and the results are observable in the compiled binary and test assertions.
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 →