Crawl4AI before 0.8.8 contains credential exfiltration vulnerabilities in the Docker API server that allow attackers to redirect LLM API calls to attacker-controlled endpoints and read arbitrary environment variables. Attackers can exploit the unauthenticated /md, /llm, and /llm/job endpoints by supplying a malicious baseurl parameter and setting apitoken to env:VARIABLENAME to exfiltrate provider API keys and server secrets including JWT SECRETKEY for authentication bypass.
Crawl4AI before 0.8.7 contains a server-side request forgery vulnerability in the /crawl, /crawl/stream, /md, and /llm endpoints that fetch arbitrary user-supplied URLs without validation. Unauthenticated attackers can bypass the internal-address blocklist using IPv6-mapped IPv4 addresses to reach internal services and cloud metadata endpoints.
Crawl4AI before 0.8.7 contains an authentication bypass vulnerability due to a hardcoded default JWT signing key in the Docker API server. Attackers who know the default key can forge valid authentication tokens for any user, bypassing authentication and gaining full access to protected functionality.
Crawl4AI before 0.8.7 contains an arbitrary JavaScript execution vulnerability in the Docker API server's /executejs endpoint, which accepts and executes arbitrary user-supplied JavaScript in the server's browser context with --disable-web-security enabled. An attacker can execute arbitrary JavaScript and, combined with the browser's relaxed security settings, perform server-side request forgery against internal services.
Crawl4AI before 0.8.7 contains a stored cross-site scripting vulnerability in the monitor dashboard that renders crawl URLs and error messages via innerHTML without escaping. An attacker can submit a crafted crawl request with malicious markup that executes in an operator's browser when viewing the dashboard.
Crawl4AI before 0.8.7 contains an authentication bypass vulnerability in the monitor router endpoints that allows unauthenticated attackers to access destructive operations. Remote attackers can invoke the /monitor/actions/cleanup endpoint and manipulate monitoring state without authentication, causing service disruption.
Crawl4AI before 0.8.7 contains a server-side request forgery (SSRF) vulnerability in the Docker API server's /crawl/job and /llm/job endpoints, which accept webhook URLs without destination validation. An attacker can supply webhook URLs pointing to private or internal IP ranges, Docker networks, or cloud metadata endpoints (e.g. 169.254.169.254), causing the server to make requests to internal services and potentially expose cloud metadata.
Crawl4AI before 0.8.7 contains an arbitrary file write vulnerability in the Docker API server's /screenshot and /pdf endpoints. The outputpath parameter accepts arbitrary filesystem paths without validation, allowing an attacker to supply absolute or path-traversal values to write to any location writable by the application's user, overwriting server files and causing denial of service.
Crawl4AI before 0.8.8 contains an arbitrary file write vulnerability in the screenshot and PDF endpoints that allows unauthenticated attackers to write files outside the intended directory via symlink and time-of-check-time-of-use (TOCTOU) attacks on the outputpath parameter. Remote attackers can exploit insufficient path validation and symlink following to achieve arbitrary file write and potential code execution on systems where the runtime user has write access to executable or cron locations.
Crawl4AI versions prior to 0.8.0 contain a remote code execution vulnerability in the Docker API deployment. The /crawl endpoint accepts a hooks parameter containing Python code that is executed using exec(). The import builtin was included in the allowed builtins, allowing unauthenticated remote attackers to import arbitrary modules and execute system commands. Successful exploitation allows full server compromise, including arbitrary command execution, file read and write access, sensitive data exfiltration, and lateral movement within internal networks.
Crawl4AI versions prior to 0.8.0 contain a local file inclusion vulnerability in the Docker API deployment. The /executejs, /screenshot, /pdf, and /html endpoints accept file:// URLs, allowing unauthenticated remote attackers to read arbitrary files from the server filesystem. An attacker can access sensitive files such as /etc/passwd, /etc/shadow, application configuration files, and environment variables via /proc/self/environ, potentially exposing credentials, API keys, and internal application structure.
Crawl4AI is an open-source LLM-friendly web crawler and scraper. Prior to 0.9.0, the Docker API server accepted request-supplied browserconfig.extraargs, which flowed into Chromium's launch arguments. An attacker could inject Chromium switches that replace a child-process launch command together with --no-zygote, causing Chromium to fork or exec an attacker-controlled command as the container's runtime user. The Docker API is unauthenticated by default, so a single request yields arbitrary command execution. This issue is fixed in version 0.9.0.
Crawl4AI is an open-source LLM-friendly web crawler and scraper. Prior to 0.9.0, the Docker API server applied its SSRF destination check on the non-streaming /crawl path but not on the streaming path. handlestreamcrawlrequest passed seed URLs straight to the crawler with no destination validation, allowing a remote unauthenticated client to call POST /crawl/stream or POST /crawl with crawlerconfig.stream=true with a URL pointing at an internal, private, or link-local address; the server fetched it and streamed the response body back. This issue is fixed in version 0.9.0.
Crawl4AI is an open-source LLM-friendly web crawler and scraper. Prior to 0.9.0, 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 or traversal escaped the downloads directory, giving an arbitrary file write with attacker-controlled contents; the HTTP crawler path uses the response Content-Disposition filename and the browser crawler path uses the download's suggested filename. Because the written bytes are attacker-controlled, this can escalate to remote code execution. This issue is fixed in version 0.9.0.
Summary
The safeevalexpression() function in the computed fields feature uses an AST validator that only blocks attributes starting with underscore. Python generator and frame object attributes (giframe, fback, fbuiltins) do NOT start with underscore, enabling a complete sandbox escape to achieve arbitrary code execution.
The attack requires no authentication (JWT disabled by default) and is triggered via POST /crawl with a crafted extraction schema.
Attack Vector
An attacker sends a POST /crawl request with a JsonCssExtractionStrategy schema containing a malicious computed field expression that: 1. Creates a generator to access giframe 2. Walks the frame chain via fback 3. Reaches fbuiltins containing the real import 4. Imports os and executes arbitrary commands
Impact
Unauthenticated remote code execution inside the Docker container. An attacker can execute arbitrary system commands, read/write files, and exfiltrate secrets.
Fix Details
1. Removed eval() from computed field expression path entirely -- expressions now log a warning and return default value 2. Deleted safeevalexpression() function and SAFEEVALBUILTINS (dead security-sensitive code) 3. function key with Python callables still works for SDK users 4. Replaced eval() in /config/dump with JSON-based input validated by Pydantic 5. Fixed hookmanager sandbox: stripped builtins, loader, spec from injected modules; removed getattr, setattr, type, buildclass from allowed builtins
Workarounds
1. Upgrade to the patched version (recommended) 2. Enable JWT authentication via CRAWL4AIAPITOKEN environment variable 3. Restrict network access to the Docker API
Credits
- Song Binglin (q1uf3ng) - reported the AST sandbox escape - by111 (August829) - reported the hook sandbox builtins escape and hardcoded JWT secret bypass - jannahopp - PR #1855 proposing eval removal - ntohidi - PR #1886 proposing allowlist approach
Summary
The Docker API server's SSRF protection (validatewebhookurl / validateurldestination in deploy/docker/utils.py) used an explicit IPv4/IPv6 CIDR blocklist that missed several address families. An attacker could reach internal services and cloud metadata endpoints (e.g. 169.254.169.254) despite the filter by encoding an internal IPv4 address inside an IPv6 transition form, or by using the IPv6 unspecified address.
Because the Docker API is unauthenticated by default (jwtenabled: false), no credentials are required.
Affected paths
The blocklist was applied to crawl URLs (POST /crawl, /md, /html, /screenshot, /pdf, /executejs) and webhook URLs (/crawl/job, /llm/job). All shared the same incomplete check.
Bypasses
The following all resolve to (or route to) blocked internal addresses but were NOT caught: - IPv6 unspecified :: - NAT64 64:ff9b::a9fe:a9fe (embeds 169.254.169.254) - 6to4 2002:a9fe:a9fe:: (embeds 169.254.169.254) - IPv4-mapped ::ffff:169.254.169.254 - IPv4-compatible ::a9fe:a9fe
The error message also echoed the resolved internal IP, acting as a minor DNS/oracle leak.
Impact
Server-Side Request Forgery: an unauthenticated attacker can make the server fetch internal-network URLs and cloud instance-metadata endpoints, potentially exposing internal services and cloud credentials.
Fix
The blocklist is replaced by a single rule: reject any resolved IP where not ip.isglobal, evaluated on the address AND every embedded IPv4 transition form (v4-mapped, NAT64 64:ff9b::/96, 6to4 2002::/16, v4-compat ::/96). Error messages are now opaque and no longer echo the resolved IP.
Workarounds
- Upgrade to the patched version. - Enable authentication (CRAWL4AIAPITOKEN). - Restrict the container's outbound network access (egress firewall / no metadata route).
Credits
Internal security audit (Crawl4AI maintainers).
Summary
The Docker API server applied its SSRF destination check to the crawl target URL only, not to the proxy address. An unauthenticated request could supply a proxy pointing at an internal IP and route the browser through it, reaching internal services and cloud-metadata endpoints, while using a perfectly valid crawl URL. The Docker API is unauthenticated by default.
Affected paths
/crawl, /crawl/stream, and /crawl/job accept a browserconfig (and crawlerconfig). The following all feed Chromium's egress and were unchecked: - browserconfig.proxyconfig.server - browserconfig.proxy (deprecated field) - crawlerconfig.proxyconfig.server - --proxy-server / --proxy-pac-url / --proxy-bypass-list / --host-resolver-rules flags in browserconfig.extraargs
Attack
An attacker sends /crawl with a benign, validation-passing URL but a proxyconfig.server pointing at an internal IP. Chromium routes all requests through that proxy. For plain-HTTP targets the proxy receives the full request and can return any content, which is then returned verbatim in the crawl result (results[0].html / cleanedhtml / markdown). In a real deployment the proxy would be an attacker-controlled server pointing at cloud metadata (e.g. AWS IMDSv1 at 169.254.169.254) to retrieve IAM credential tokens.
Impact
Unauthenticated server-side request forgery to internal services and cloud-metadata endpoints, with the response returned to the attacker.
Fix
Every proxy destination is validated with the same global-routability check used for crawl URLs (reject any resolved address that is not isglobal, including IPv6 transition forms) before the browser is constructed; proxy/DNS-redirecting flags are stripped from extraargs. A legitimate public proxy still works. Honors CRAWL4AIALLOWINTERNALURLS.
Workarounds
- Upgrade to the patched version (0.8.9). - Enable authentication (CRAWL4AIAPITOKEN). - Restrict the container's outbound network access (egress firewall / no metadata route).
Credits
Geo (geo-chen) - reported the proxyconfig.server SSRF with a clear PoC.