# How C++ Patches in CloakBrowser Remove Automation Signals: navigator.webdriver and chrome

> Learn how CloakBrowser uses C++ patches to remove automation signals like navigator.webdriver and chrome, bypassing detection and ensuring a genuine browser experience.

- Repository: [CloakHQ/CloakBrowser](https://github.com/CloakHQ/CloakBrowser)
- Tags: deep-dive
- Published: 2026-05-09

---

**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`](https://github.com/CloakHQ/CloakBrowser/blob/main/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`](https://github.com/CloakHQ/CloakBrowser/blob/main/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`](https://github.com/CloakHQ/CloakBrowser/blob/main/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`](https://github.com/CloakHQ/CloakBrowser/blob/main/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`](https://github.com/CloakHQ/CloakBrowser/blob/main/tests/test_stealth.py) (lines 36-38) explicitly asserts that `navigator.webdriver` returns `false`:

```python
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`](https://github.com/CloakHQ/CloakBrowser/blob/main/tests/test_launch.py) (lines 44-49) validates these properties immediately after launch:

```javascript
// 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.webdriver` to `false` in the C++ getter implementation.
- **`window.chrome`** is restored as a proper object matching genuine Chrome behavior, eliminating headless fingerprints.
- **No `--enable-automation` flag** is passed, preventing the runtime exposure of automation signals.
- **Test coverage** in [`tests/test_stealth.py`](https://github.com/CloakHQ/CloakBrowser/blob/main/tests/test_stealth.py) and [`tests/test_launch.py`](https://github.com/CloakHQ/CloakBrowser/blob/main/tests/test_launch.py) verifies 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`](https://github.com/CloakHQ/CloakBrowser/blob/main/tests/test_stealth.py) asserts that `navigator.webdriver` is `false` and [`tests/test_launch.py`](https://github.com/CloakHQ/CloakBrowser/blob/main/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`](https://github.com/CloakHQ/CloakBrowser/blob/main/CHANGELOG.md) and [`README.md`](https://github.com/CloakHQ/CloakBrowser/blob/main/README.md), and the results are observable in the compiled binary and test assertions.