VoidCrawl uses a minimal-footprint stealth strategy inspired by undetected-chromedriver◑, zendriver△, and nodriver○. Stealth is enabled by default.
Philosophy: Less Is More
Most browser automation tools try to spoof every fingerprint signal — fake plugins, fake WebGL, fake user-agent strings. This backfires against modern WAFs (Akamai, Cloudflare, PerimeterX) because:
Spoofed values are inconsistent. A hardcoded Chrome/131 user-agent on a system running Chromium 146 is an instant flag.
The spoofing itself is detectable. Each Page.addScriptToEvaluateOnNewDocument CDP call is a fingerprint. Overriding navigator.plugins with a Proxy/getter behaves differently from the real PluginArray prototype.
The automation signal isn’t in JS — it’s in Chrome’s launch flags. chromiumoxide’s default flags include --enable-automation, which tells every WAF “I’m automated” before any page loads.
VoidCrawl’s approach: don’t fake anything except the one property Chrome explicitly sets for automation (navigator.webdriver). Instead, launch Chrome with clean flags that don’t advertise automation.
This polls document.body.innerHTML.length every 300ms and considers the page ready when the size stabilizes above the minimum threshold. It prevents redirect gates, loading spinners, and challenge pages from being mistaken for real content.
Disabling Stealth
from voidcrawl import BrowserConfig, BrowserSession
asyncwithBrowserSession(BrowserConfig(stealth=False)) as session:
No. VoidCrawl’s stealth handles most common WAFs (Akamai, Cloudflare basic). Advanced protections that analyze traffic patterns, require CAPTCHAs, or use device attestation are outside the current scope.
Does stealth add latency?
Negligible. The JS patches are injected once per tab creation via addScriptToEvaluateOnNewDocument and execute before any page script. The flag changes are applied at Chrome launch time with zero runtime cost.
Why not use a custom user-agent?
A custom UA that doesn’t match the actual Chrome version is an instant detection signal. VoidCrawl uses Chrome’s real user-agent, which is always consistent with the actual browser binary.