---
id: CVE-2026-56258
aliases:
  - GHSA-7cx2-g3h9-382p
  - PYSEC-2026-228
title: >-
  Crawl4AI: Arbitrary file write (symlink/TOCTOU) plus log and webhook-header
  injection in Docker server
summary: >-
  Crawl4AI: Arbitrary file write (symlink/TOCTOU) plus log and webhook-header
  injection in Docker server
severity: high
cvss: 8.1
cvssVector: 'CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H'
vendor: crawl4ai
product: crawl4ai
ecosystem: pip
affected:
  - crawl4ai < 0.8.8
patched:
  - crawl4ai 0.8.8
published: '2026-06-16'
updated: '2026-07-21'
source: OSV
sourceUrl: 'https://osv.dev/vulnerability/GHSA-7cx2-g3h9-382p'
references:
  - url: >-
      https://github.com/unclecode/crawl4ai/security/advisories/GHSA-7cx2-g3h9-382p
  - url: 'https://github.com/unclecode/crawl4ai/issues/1'
  - url: 'https://github.com/unclecode/crawl4ai/issues/2'
  - url: 'https://github.com/unclecode/crawl4ai/pull/3'
  - url: >-
      https://github.com/pypa/advisory-database/tree/main/vulns/crawl4ai/PYSEC-2026-228.yaml
  - url: 'https://github.com/unclecode/crawl4ai'
  - url: >-
      https://www.vulncheck.com/advisories/crawl4ai-arbitrary-file-write-via-output-path-symlink-and-toctou
tags:
  - osv
  - pip
epss: 0.00912
epssPercentile: 0.58556
ingestedAt: '2026-07-21T19:04:56.491Z'
---

## Overview

### Summary

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 packages

- `crawl4ai < 0.8.8`

## Remediation

Upgrade to a patched release:

- `crawl4ai 0.8.8`
