GHSA-2jq4-q6vv-4cp3: Crawl4AI: Arbitrary file write (path traversal) in crawler downloads can lead to RCE
Summary When the crawler saves a downloaded file, the destination filename was taken from attacker-influenced input and joined to the downloads directory with no confinement. A filename containing an absolute path (e.g. /etc/cron.d/evil) or ../ traversal escaped the downloads directory, giving an arbitrary file write with attacker-controlled contents.
Published Jun 18, 2026
Affected packages
crawl4ai
- Ecosystem
- PyPI
- Affected
- <= 0.8.9
- Fixed in
- 0.9.0
- Check
pip show crawl4ai
Advisory details
From the GitHub Advisory Database (CC BY 4.0).
Summary
When the crawler saves a downloaded file, the destination filename was taken from attacker-influenced input and joined to the downloads directory with no confinement. A filename containing an absolute path (e.g. /etc/cron.d/evil) or ../ traversal escaped the downloads directory, giving an arbitrary file write with attacker-controlled contents. Because the written bytes are attacker-controlled, this escalates to remote code execution (overwriting a shell rc-file, ~/.ssh/authorized_keys, a cron entry, or a Python module on the import path).
Affected paths
Two download sinks in crawl4ai/async_crawler_strategy.py:
- HTTP crawler (
AsyncHTTPCrawlerStrategy): the filename is parsed from the responseContent-Dispositionheader by_extract_filename()and written viaaiofiles.open(filepath, 'wb'). Reachable directly via the SDK, and via the unauthenticated Docker/crawlendpoint when anHTTPCrawlerConfigis supplied. - Browser crawler (
AsyncPlaywrightCrawlerStrategy): the download'ssuggested_filename(controllable by the visited page) is joined todownloads_pathand written viadownload.save_as().
The HTTP-strategy sink is reachable pre-auth on the default Docker deployment; both are reachable for SDK users simply by crawling an attacker-controlled URL. The default Playwright crawl path that does not trigger a download is unaffected.
Impact
Arbitrary file write with attacker-controlled content as the user running the crawler, escalating to remote code execution.
Fix
Both sinks now resolve the destination through a single hardened helper (_safe_download_filepath) that reduces the attacker-influenced name to a bare basename (dropping absolute paths and .. components) and re-checks, via realpath, that the resolved path stays inside the downloads root (defeating symlink/TOCTOU escapes). A traversal attempt is rejected; normal downloads are unchanged.
Workarounds
- Upgrade to the patched version (0.9.0).
- Run the crawler as an unprivileged user with a dedicated, isolated downloads directory on a volume with no sensitive paths writable.
- Enable authentication (
CRAWL4AI_API_TOKEN) on the Docker server.
Credits
Y4tacker - reported the Content-Disposition path traversal in the HTTP crawler with a clear PoC and a basename + realpath-containment fix recommendation.
References
How this page is made: the data panel comes from the GitHub Advisory Database, CISA’s KEV catalog, the NVD and FIRST EPSS, and updates twice a day. No analysis has been written for this entry yet. Methodology
More PyPI vulnerabilities
All PyPI entriesCVE-2026-56265
Crawl4AI: authentication bypass vulnerability due to a hardcoded default JWT signing key in the Docker API server
critical9.8Jun 21, 2026GHSA-r253-r9jw-qg44
Crawl4AI: Unauthenticated RCE via Chromium launch-argument injection in browser_config.extra_args
critical10.0Jun 18, 2026CVE-2026-53753
Crawl4AI: AST Sandbox Escape via gi_frame.f_back Chain - Pre-Auth RCE in Docker API
critical9.8Jun 16, 2026CVE-2026-56266
Crawl4AI: Multiple Docker API Vulnerabilities - File Write, SSRF, Auth Bypass, XSS, JS Execution
critical9.8Jun 16, 2026CVE-2026-26217
Crawl4AI Has Local File Inclusion in Docker API via file:// URLs
critical8.6Jan 16, 2026
