GHSA-7CX2-G3H9-382P
Vulnerability from github – Published: 2026-06-16 21:02 – Updated: 2026-06-16 21:02Summary
Three backward-compatible hardening fixes in the Docker API server. The headline issue is an arbitrary file write via the screenshot/PDF output_path.
1. Arbitrary file write via output_path symlink / TOCTOU (primary)
POST /screenshot and POST /pdf accept an output_path constrained to ALLOWED_OUTPUT_DIR by validate_output_path. The 0.8.7 check was string-only: it did not resolve symlinks, so a symlinked path component inside the output directory could redirect the write outside the directory, and the final open() followed symlinks. On a deployment where the runtime user can write executable/cron locations this is an arbitrary-write to code-execution primitive. The API is unauthenticated by default.
Fix: validate_output_path now resolves the real path (symlinks) of the parent and re-checks containment, and the write uses O_NOFOLLOW (write_output_file). output_path remains supported.
2. CRLF log injection (CWE-117)
User-controlled URLs/errors reflected into log lines could embed CR/LF and forge additional log entries. Fix: a logging filter strips CR/LF/control characters from all records.
3. Webhook request-header injection (CWE-93/CWE-113)
User-supplied webhook headers were sent verbatim, allowing CRLF and hop-by-hop / sensitive header injection on the outbound webhook request. Fix: webhook headers are validated (name pattern, no control characters, deny Host/Content-Length/Transfer-Encoding/Authorization/Cookie/...), with early request-time rejection.
Impact
Arbitrary file write (potential code execution) for #1; log forging for #2; request smuggling / header injection on outbound webhooks for #3.
Workarounds
- Upgrade to the patched version.
- Enable authentication (
CRAWL4AI_API_TOKEN). - Run the container with a read-only root filesystem.
Credits
Internal security audit (Crawl4AI maintainers).
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 0.8.7"
},
"package": {
"ecosystem": "PyPI",
"name": "crawl4ai"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.8.8"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-117",
"CWE-22",
"CWE-59",
"CWE-93"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-16T21:02:19Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "### Summary\n\nThree backward-compatible hardening fixes in the Docker API server. The headline issue is an arbitrary file write via the screenshot/PDF `output_path`.\n\n### 1. Arbitrary file write via output_path symlink / TOCTOU (primary)\n\n`POST /screenshot` and `POST /pdf` accept an `output_path` constrained to `ALLOWED_OUTPUT_DIR` by `validate_output_path`. The 0.8.7 check was string-only: it did not resolve symlinks, so a symlinked path component inside the output directory could redirect the write outside the directory, and the final `open()` followed symlinks. On a deployment where the runtime user can write executable/cron locations this is an arbitrary-write to code-execution primitive. The API is unauthenticated by default.\n\nFix: `validate_output_path` now resolves the real path (symlinks) of the parent and re-checks containment, and the write uses `O_NOFOLLOW` (`write_output_file`). `output_path` remains supported.\n\n### 2. CRLF log injection (CWE-117)\n\nUser-controlled URLs/errors reflected into log lines could embed CR/LF and forge additional log entries. Fix: a logging filter strips CR/LF/control characters from all records.\n\n### 3. Webhook request-header injection (CWE-93/CWE-113)\n\nUser-supplied webhook headers were sent verbatim, allowing CRLF and hop-by-hop / sensitive header injection on the outbound webhook request. Fix: webhook headers are validated (name pattern, no control characters, deny `Host`/`Content-Length`/`Transfer-Encoding`/`Authorization`/`Cookie`/...), with early request-time rejection.\n\n### Impact\n\nArbitrary file write (potential code execution) for #1; log forging for #2; request smuggling / header injection on outbound webhooks for #3.\n\n### Workarounds\n\n- Upgrade to the patched version.\n- Enable authentication (`CRAWL4AI_API_TOKEN`).\n- Run the container with a read-only root filesystem.\n\n### Credits\n\nInternal security audit (Crawl4AI maintainers).",
"id": "GHSA-7cx2-g3h9-382p",
"modified": "2026-06-16T21:02:19Z",
"published": "2026-06-16T21:02:19Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/unclecode/crawl4ai/security/advisories/GHSA-7cx2-g3h9-382p"
},
{
"type": "WEB",
"url": "https://github.com/unclecode/crawl4ai/issues/1"
},
{
"type": "WEB",
"url": "https://github.com/unclecode/crawl4ai/issues/2"
},
{
"type": "WEB",
"url": "https://github.com/unclecode/crawl4ai/pull/3"
},
{
"type": "PACKAGE",
"url": "https://github.com/unclecode/crawl4ai"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "Crawl4AI: Arbitrary file write (symlink/TOCTOU) plus log and webhook-header injection in Docker server"
}
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.