chaser-cf
Cloudflare bypass library powered by stealth browser automation. No captcha API tokens needed — pure browser-based challenge solving with C FFI bindings for use from any language.
How it works
- Launches a real Chrome instance with a native fingerprint (OS, RAM, UA, Client Hints all consistent)
- For WAF/managed challenges: polls for
cf_clearanceand clicks the Turnstile checkbox via CDP shadow-root traversal — Cloudflare's widget lives inside a closed shadow root that JS can't reach, but CDP can - For Turnstile tokens: injects an extractor script and optionally intercepts the page request to serve a minimal HTML stub, reducing load time and noise
- Built on chaser-oxide, a stealth fork of chromiumoxide
Features
- WAF Session — extracts
cf_clearance+user-agentfor use in subsequent HTTP requests - Turnstile max — solves Turnstile with full page load (no site key needed)
- Turnstile min — solves Turnstile with request interception, much faster (site key required)
- Page source — returns HTML after challenge is cleared
- Proxy support — per-request proxy with optional auth
- Virtual display — Xvfb-backed headed Chrome on Linux servers (required for CF managed challenges)
- C FFI — use from Python, Go, Node.js, C/C++, etc.
- HTTP server — optional REST API (feature-flagged)
Installation
[]
= { = "0.2.0" }
Requires Chrome or Chromium installed on the system.
Usage
Rust
use ;
async
With proxy:
use ProxyConfig;
let proxy = new
.with_auth;
let session = chaser.solve_waf_session.await?;
Configuration
let config = default
.with_context_limit // max concurrent browser contexts
.with_timeout_ms // per-operation timeout
.with_lazy_init // don't launch browser until first use
.with_headless // headless mode (see note below)
.with_virtual_display // Linux: start Xvfb, run Chrome headed inside it
.with_chrome_path
.add_extra_arg; // required when running as root
| Option | Default | Description |
|---|---|---|
context_limit |
20 | Max concurrent browser contexts |
timeout_ms |
60000 | Per-operation timeout (ms) |
lazy_init |
false | Defer browser launch until first use |
headless |
false | Run browser headless |
virtual_display |
false | Linux: use Xvfb virtual display (overrides headless) |
extra_args |
[] |
Extra Chrome flags (e.g. --no-sandbox, --disable-gpu) |
chrome_path |
auto | Path to Chrome/Chromium binary |
Linux server deployment
Cloudflare's managed/interactive challenge detects headless Chrome at the binary level. On Linux servers, use --virtual-display to run Chrome headed inside an Xvfb virtual framebuffer — this is the same approach used by cf-clearance-scraper and other public bypass tools.
let config = default
.with_virtual_display
.add_extra_arg; // if running as root
Or via environment variables:
CHASER_VIRTUAL_DISPLAY=true CHASER_EXTRA_ARGS="--no-sandbox"
Headless mode (with_headless(true)) works for Turnstile-only flows (min/max) but will fail CF WAF/managed challenges — use virtual_display for those.
Testing
)
)
)
)
|||)
# Examples
HTTP Server
# WAF session
# Page source
# Turnstile (full page)
# Turnstile (minimal)
# With proxy
Environment variables
| Variable | Default | Description |
|---|---|---|
PORT |
3000 |
HTTP server port |
CHASER_CONTEXT_LIMIT |
20 |
Max concurrent contexts |
CHASER_TIMEOUT |
60000 |
Timeout (ms) |
CHASER_LAZY_INIT |
false |
Lazy browser init |
CHASER_HEADLESS |
false |
Headless mode |
CHASER_VIRTUAL_DISPLAY |
false |
Xvfb virtual display (Linux) |
CHASER_EXTRA_ARGS |
none | Whitespace-separated Chrome flags (e.g. --no-sandbox --disable-gpu) |
CHROME_BIN |
auto | Chrome binary path |
AUTH_TOKEN |
none | Optional API auth token |
C FFI
Build the shared library:
# headers written to include/chaser_cf.h
void
int
Python (ctypes)
=
=
=
Response format
License
MIT OR Apache-2.0