CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-2JQ4-Q6VV-4CP3

GHSA-2JQ4-Q6VV-4CP3: Arbitrary File Write via Path Traversal in Crawl4AI Downloads

Amit Schendel
Amit Schendel
Senior Security Researcher

Jun 18, 2026·5 min read·22 visits

Executive Summary (TL;DR)

Crawl4AI <= 0.8.9 allows arbitrary file write and path traversal, potentially leading to RCE via unauthenticated /crawl endpoints or victim-initiated crawling.

A critical Arbitrary File Write vulnerability exists in Crawl4AI versions 0.8.9 and below. By manipulating download filenames via Content-Disposition headers or suggested_filename values, attackers can write arbitrary files to any location on the file system, potentially leading to Remote Code Execution.

Vulnerability Overview

Crawl4AI is an open-source Python package widely utilized for web crawling and scraping tasks, particularly in artificial intelligence and machine learning pipelines. The tool features dual crawling strategies: an HTTP-based approach utilizing AsyncHTTPCrawlerStrategy and a browser-based approach powered by Playwright through AsyncPlaywrightCrawlerStrategy. Both engines expose download capabilities intended to store media and file attachments retrieved during crawls.

In versions 0.8.9 and prior, these download features contain an improper pathname limitation vulnerability (CWE-22). The attack surface includes any application execution path where the crawler parses an external, untrusted web resource that redirects to or initiates a file download. Because the crawler does not neutralize directory traversal sequences before processing paths, an attacker can manipulate target outputs to escape the intended downloads directory.

Root Cause Analysis

The root cause of this vulnerability lies in the unvalidated trust placed in remote server headers and DOM properties during download resolution. When the HTTP crawler processes a remote resource, it reads the Content-Disposition header and passes it to self._extract_filename(). The resulting filename is combined directly with the downloads path using os.path.join.

In Python, os.path.join(path, *paths) resolves absolute paths or directory traversal sequences (such as ../) by appending them dynamically. If the filename parameter contains relative parent directory symbols, the resulting resolved path escapes the bounds of the configured target folder. The application then proceeds to open and write raw bytes to this unresolved filepath using aiofiles.open() without path confinement checks.

Similarly, the browser-based crawling strategy relies on Playwright's download.suggested_filename property. This property is also generated from remote HTTP response metadata. If the crawled webpage triggers a download with a name containing traversal components, os.path.join() behaves identically, leading to an out-of-bounds file write via Playwright's save_as() mechanism.

Code Analysis

To understand the vulnerabilities in version 0.8.9, examine the file download paths in crawl4ai/async_crawler_strategy.py before and after the patch. In the vulnerable version, paths are joined directly:

# Vulnerable Path Resolution (Crawl4AI <= 0.8.9)
filename = self._extract_filename(content_disposition, url, content_type)
filepath = os.path.join(downloads_path, filename)
async with aiofiles.open(filepath, 'wb') as f:
    await f.write(raw_bytes)

The remediation introduced in commit 60886d1a0c52682e4c83a7cef9dfac417fff6bd2 wraps path resolution in a hardened helper function _safe_download_filepath() and enforces strict symlink-blocking mechanisms:

def _safe_download_filepath(downloads_path: str, filename: str) -> str:
    # Restrict filename strictly to its base name component
    safe_name = os.path.basename(filename or "")
    if not safe_name or safe_name in (".", ".."):
        safe_name = f"download_{hashlib.md5((filename or '').encode()).hexdigest()[:10]}"
    
    real_root = os.path.realpath(downloads_path)
    real_path = os.path.realpath(os.path.join(real_root, safe_name))
    
    # Verify path confinement inside the root directory
    if os.path.commonpath([real_root, real_path]) != real_root:
        raise ValueError(f"Unsafe download filename rejected: {filename!r}")
    return real_path

To address time-of-check to time-of-use (TOCTOU) race conditions, files are opened with a custom file opener implementing O_NOFOLLOW:

def _nofollow_opener(path, flags):
    return os.open(path, flags | os.O_NOFOLLOW)
 
# Safe File Write Integration
async with aiofiles.open(filepath, 'wb', opener=_nofollow_opener) as f:
    await f.write(raw_bytes)

This implementation prevents the crawler from following malicious symbolic links planted in the directory during execution.

Exploitation and Attack Methodology

An attacker can exploit this vulnerability through two separate vectors depending on the integration context of Crawl4AI. The first vector involves self-hosted Docker instances where the /crawl API endpoint runs without authentication by default. An attacker sends a POST request specifying a target URL under their control. When Crawl4AI initiates a connection to the attacker-controlled server, the server responds with a malicious payload and a crafted Content-Disposition header.

Content-Disposition: attachment; filename="../../../../../root/.bashrc"

Upon receiving the response, the crawler resolves the target path to /root/.bashrc instead of the expected downloads subdirectory, subsequently overwriting the shell configuration file with attacker-controlled instructions. The next time an interactive shell is initialized within the container, the injected shell code executes.

The second vector affects developers utilizing the Crawl4AI Python library locally. If the developer invokes crawler.arun() on an untrusted web page, the target site can trigger a browser-driven download where the Playwright-derived suggested_filename contains a directory escape string, executing the same out-of-bounds file-writing sequence on the host machine.

Impact Assessment

The impact of an arbitrary file write vulnerability depends heavily on the execution environment and user privileges. Because Crawl4AI is frequently deployed inside Docker containers running as the root user, the write primitive can be used to execute arbitrary commands. Attackers can overwrite sensitive files such as /etc/cron.d/malicious_job to register system tasks or append credentials to ~/.ssh/authorized_keys for direct network access.

Even in unprivileged user spaces, write capability into Python's package path (e.g., modifying libraries in the active sys.path) allows attackers to inject malicious Python files. This triggers execution when subsequent modules are loaded by the application. Under CVSS 3.1, this is rated at a score of 9.6 due to the high severity of remote execution capabilities, lack of required privileges, and minimal user interaction involved.

Mitigation and Remediation

Remediation requires upgrading the crawl4ai package to version 0.9.0 or higher. This version implements robust path validation using realpath checks, blocks symlink traversal via O_NOFOLLOW, and ensures secure default behavior.

For environments where immediate upgrading is not feasible, several defensive workarounds should be applied. First, execute the web crawler process under an unprivileged system user with minimal file system write permissions. Second, run the Crawl4AI engine in a separate, isolated volume mount that contains no system-critical configuration directories or executable code. Finally, secure the /crawl endpoint with an explicit API token to restrict unauthorized usage.

Fix Analysis (1)

Technical Appendix

CVSS Score
9.6/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H

Affected Systems

Crawl4AI (Python package) <= 0.8.9

Affected Versions Detail

Product
Affected Versions
Fixed Version
crawl4ai
unclecode
<= 0.8.90.9.0
AttributeDetail
CWE IDCWE-22, CWE-59
Attack VectorNetwork (AV:N)
CVSS Score9.6 (Critical)
ImpactArbitrary File Write / Remote Code Execution
Exploit StatusProof-of-Concept
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1210Exploitation of Remote Services
Initial Access
T1059Command and Scripting Interpreter
Execution
T1546Event Triggered Execution
Persistence
CWE-22
Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

The software uses external input to construct a pathname that is intended to identify a file or directory that is located beneath a restricted parent directory, but the software does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location outside of the restricted directory.

Vulnerability Timeline

Vulnerable download code introduced in version 0.8.8/0.8.9
2026-03-16
Vulnerability identified and reported by Y4tacker
2026-06-18
Patch released in version 0.9.0 and GHSA published
2026-06-18

References & Sources

  • [1]GitHub Security Advisory GHSA-2jq4-q6vv-4cp3
  • [2]GitHub Advisory Database Entry GHSA-2JQ4-Q6VV-4CP3
  • [3]Fix Commit in unclecode/crawl4ai
  • [4]Crawl4AI Repository

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•29 minutes ago•CVE-2026-61544
8.2

CVE-2026-61544: Remote Panic in libp2p-quic via Certificate Expiry Race

CVE-2026-61544 is a high-severity remote Denial of Service (DoS) vulnerability in libp2p-quic, the QUIC transport implementation of the official Rust networking stack for libp2p. It allows unauthenticated remote attackers to trigger an uncaught panic and crash listener applications.

Alon Barad
Alon Barad
1 views•7 min read
•about 1 hour ago•CVE-2026-88975
7.5

CVE-2026-88975: Heap Memory Exhaustion via Malicious HTTP/2 Frame Size in http4s Ember

An uncontrolled resource consumption vulnerability in the http4s Ember HTTP/2 server and client implementation leads to unauthenticated heap memory exhaustion and denial of service. The vulnerability stems from deferring frame size validation until the entire declared payload size is buffered.

Amit Schendel
Amit Schendel
2 views•6 min read
•about 2 hours ago•CVE-2026-61554
7.5

CVE-2026-61554: Uncontrolled Resource Consumption in emp3r0r C2 http_poll Transport

CVE-2026-61554 is a high-severity uncontrolled resource consumption vulnerability in the http_poll transport component of the emp3r0r Command and Control (C2) framework. In affected versions prior to 4.2.5, the C2 server allocates session tracking resources, spawns execution routines, and routes incoming unauthenticated request bodies into the core dispatch engine before verifying the client's cryptographic authentication token. This logical ordering flaw allows unauthenticated remote attackers to exhaust critical host system resources and trigger a sustained denial of service.

Amit Schendel
Amit Schendel
6 views•6 min read
•about 8 hours ago•GHSA-5648-RGJ9-V224
8.1

GHSA-5648-RGJ9-V224: Multiple Security Control Bypasses in @zereight/mcp-gitlab

A constellation of five distinct security flaws (F1 through F5) in `@zereight/mcp-gitlab` prior to version 2.1.30 allows unauthenticated remote access, read-only policy bypasses, DNS rebinding, and denial-of-service via session exhaustion.

Alon Barad
Alon Barad
4 views•6 min read
•about 9 hours ago•CVE-2026-61568
9.6

CVE-2026-61568: DNS Rebinding Vulnerability in @zereight/mcp-gitlab Streamable HTTP Transport

A critical security vulnerability has been identified in the @zereight/mcp-gitlab implementation of the Model Context Protocol (MCP) server. Prior to version 2.1.30, the server lacks HTTP Host and Origin header validation on its Streamable HTTP transport interface (/mcp). This security omission permits remote attackers to bypass the Same-Origin Policy (SOP) via a DNS Rebinding attack. Under this vector, an attacker can route malicious API requests to the victim's local or internal MCP server, thereby gaining unauthorized control over the victim's GitLab account and resources.

Alon Barad
Alon Barad
9 views•9 min read
•about 10 hours ago•CVE-2026-61559
9.6

CVE-2026-61559: Critical Server-Side Request Forgery and Token Leakage in @zereight/mcp-gitlab

A critical Server-Side Request Forgery (SSRF) vulnerability in @zereight/mcp-gitlab allows attackers to leak sensitive GitLab Private-Tokens by supplying an arbitrary external hostname via the X-GitLab-API-URL header when dynamic routing is enabled.

Amit Schendel
Amit Schendel
6 views•7 min read