# Crawl4AI: Unauthenticated RCE via Chromium launch-argument injection in browser_config.extra_args

Unauthenticated Crawl4AI Docker API accepted request-supplied browser_config.extra_args, letting attackers inject Chromium switches like --utility-cmd-prefix with --no-zygote to exec arbitrary commands in the container.

- Payout: Research
- Severity: critical
- Program: Crawl4AI
- Found by: hoanggxyuuki
- Disclosed: 2026-06-18
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-r253-r9jw-qg44
- Library page: http://bugbountylibrary.com/r/ghsa%3AGHSA-r253-r9jw-qg44
- Tags: area:cloud domain:infra domain:web impact:internal-access impact:rce kind:research platform:ghsa sev:critical tech:docker technique:incomplete-fix vuln:command-injection vuln:misconfiguration vuln:rce

**Target:** Crawl4AI Docker API server (/crawl, /crawl/stream, /crawl/job) launching Chromium
**Root cause:** Request-supplied browser_config.extra_args flowed unsanitized into Chromium's launch arguments; a denylist scoped to proxy/DNS flags (added in 0.8.9) missed command-execution switches such as --utility-cmd-prefix, --renderer-cmd-prefix, --gpu-launcher, --browser-subprocess-path.
**Steps:**
1. Send an unauthenticated request to `/crawl` (or `/crawl/stream`, `/crawl/job`) with a body setting `browser_config.extra_args`.
2. Include Chromium switches `--no-zygote` plus a child-process launch override such as `--utility-cmd-prefix` (or `--renderer-cmd-prefix`, `--gpu-launcher`, `--browser-subprocess-path`) pointing at an attacker-controlled command.
3. Chromium forks/execs the injected command as the container runtime user, yielding arbitrary command execution.
**How found:** Prior 0.8.9 patch added a denylist for extra_args scoped to proxy/DNS flags; researchers recognized a denylist of Chromium launch switches is inherently incomplete and hunted for command-execution switches (--utility-cmd-prefix, --renderer-cmd-prefix) not covered, confirming reproduction on 0.8.9.
**Exploitation:** Single unauthenticated HTTP request to the default-open Docker API; injected Chromium launch switches cause fork/exec of attacker command as the container runtime user, enabling read/write of application data, mounted secrets, environment and tokens, with out-of-band exfiltration independent of the HTTP response.
**Insight:** When a fix denylists dangerous values for a passthrough field, enumerate the full capability surface of the downstream binary (here Chromium's child-process launch switches like --utility-cmd-prefix/--renderer-cmd-prefix/--gpu-launcher) rather than the originally-reported subset; a denylist on launch flags is always incomplete, so the real fix is rejecting the field from untrusted input.

