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-7HXC-F267-H5Q7

GHSA-7HXC-F267-H5Q7: Path Traversal via Validation-then-Normalization in Craft CMS

Alon Barad
Alon Barad
Software Engineer

Aug 7, 2026·8 min read·13 visits

Executive Summary (TL;DR)

Craft CMS local storage driver validates path containment before normalizing the path. This allows attackers to bypass boundary checks using protocol-prefixed traversal sequences, resulting in unauthorized local file access.

A path traversal vulnerability exists in the local filesystem driver of Craft CMS. Due to validation occurring before path normalization, directory containment checks can be bypassed by utilizing specific protocol schemes like 'file://' along with directory traversal sequences. This allows authenticated users with administrative privileges to access or manipulate files outside the defined storage root directory.

Vulnerability Overview

The local filesystem driver (Local.php) in Craft CMS is responsible for managing the physical storage and manipulation of assets within configured local storage volumes. It exposes an attack surface through asset management capabilities, where users can upload, index, or rename physical resources. To maintain security boundaries, Craft CMS enforces a directory containment validation mechanism to prevent users from referencing files outside of their designated storage root.

This vulnerability is characterized as an improper limitation of a pathname to a restricted directory, corresponding to CWE-22 and CWE-23. The flaw occurs because of a logical desynchronization between how paths are validated and how they are subsequently normalized before execution. This order-of-operations vulnerability allows directory containment validation to be bypassed completely when specific inputs are processed.

An attacker with administrative privileges or permission to modify asset configurations can submit paths that contain URI protocol schemes such as file:// alongside directory traversal sequences. Because the application evaluates security boundaries on the un-normalized string and then processes the normalized output, the safety guarantees of the filesystem driver are invalidated. This results in arbitrary file read and write operations depending on the downstream function executing the path.

Root Cause Analysis

The core issue is a validation-then-normalization vulnerability within the prefixPath method of src/fs/Local.php. When generating absolute file system paths, the application attempts to verify that the target path does not escape the storage volume root. This validation is delegated to Path::ensurePathIsContained(). Crucially, the application performs this validation check on the raw, uncanonicalized path input before any normalization takes place.

The helper method Path::ensurePathIsContained() calculates directory nesting levels by splitting the path into segments using standard separators (/ and \). It iterates through these segments, incrementing an integer counter for normal folders and decrementing it for parent directory markers (..). If this counter drops below zero, the method concludes that the path has traversed past the root directory and returns false. This simple state machine is effective for relative paths but fails when dealing with unexpected protocol prefixes.

When a path starts with a protocol scheme like file://, the validator splits the prefix into segments, such as file:. The validator treats file: as a regular subdirectory, which increments the internal depth counter. However, when the string is later processed by FileHelper::normalizePath(), a regular expression replaces the protocol prefix file:// with an empty string. The subsequent directory traversal segments (../) are then evaluated during the final canonicalization process, moving the directory depth higher than the root directory.

Because the protocol prefix artificially increases the validation depth, the directory traversal escapes the root directory without triggering the depth counter limit. The containment check succeeds, the protocol prefix is stripped during normalization, and the final absolute path resolved by the PHP engine points to local files outside the storage volume. This represents a classic validation bypass due to incorrect state tracking on desanitized parameters.

Code Analysis

To illustrate the vulnerability, we examine the original implementation of the prefixPath method in src/fs/Local.php before the patch:

protected function prefixPath(string $path = ''): string
{
    // Step 1: Validate containment on raw path input
    if (!Path::ensurePathIsContained($path)) {
        throw new FsException("The path `$path` is not contained.");
    }
 
    // Step 2: Normalize the path and append to the root directory
    return $this->getRootPath() . DIRECTORY_SEPARATOR . FileHelper::normalizePath($path);
}

The validator splits the input on forward and backward slashes. Consider the payload a/b/c/d/file://../../../../etc/passwd. The parsed segment list contains ['a', 'b', 'c', 'd', 'file:', '..', '..', '..', '..', 'etc', 'passwd']. The containment check processes these segments, raising the depth counter to five before encountering four parent directory indicators. The final depth counter never falls below zero, and validation succeeds. Next, the string is passed to FileHelper::normalizePath() which executes a regular expression clean-up:

public static function normalizePath($path, $ds = DIRECTORY_SEPARATOR): string
{
    // Strip file protocol wrappers
    $path = preg_replace('/^(file:\\/\\/)*/i', '', $path);
    ...
    $path = parent::normalizePath($path, $ds);
    return $path;
}

The regular expression strips out the file:// string, leaving a/b/c/d/../../../../etc/passwd. The underlying parent class resolves the parent directory markers, collapsing the string to ../etc/passwd. The function returns this relative path to prefixPath(), which concatenates it with the root path, producing /var/www/web/uploads/../etc/passwd. This path escapes the restricted boundary.

The vulnerability was corrected by changing the order of operations in src/fs/Local.php to ensure the input is normalized first:

protected function prefixPath(string $path = ''): string
{
    // Step 1: Normalize the path first
    $path = FileHelper::normalizePath($path);
 
    // Step 2: Perform containment checks on the normalized path
    if (!Path::ensurePathIsContained($path)) {
        throw new FsException("The path `$path` is not contained.");
    }
 
    // Step 3: Use the verified normalized path
    return $this->getRootPath() . DIRECTORY_SEPARATOR . $path;
}

In the patched version, the input a/b/c/d/file://../../../../etc/passwd is normalized to ../etc/passwd first. When passed to the validator, the initial segment .. immediately reduces the depth counter to -1, resulting in a validation failure and throwing an FsException. This fix is logically sound and completely addresses the desynchronization bug.

Exploitation Methodology

Exploitation of this vulnerability requires the attacker to have administrative or specific privileged access within Craft CMS. The attacker must target asset-management endpoints or configurations that accept user-controlled path parameters, such as the asset indexing tool or folders associated with local volumes. Because these tools translate user configurations into physical path resolutions, they act as the execution interface for the underlying filesystem driver.

To construct an exploit payload, the attacker must calculate the necessary depth of the target directory structure. If the volume root is located at /var/www/web/storage/user_uploads, the attacker needs to traverse four directory levels upward to reach the system root. To do this, the attacker creates a payload containing four directory padding segments, a file:// scheme, and four .. traversal sequences.

An example payload is formulated as follows:

folder1/folder2/folder3/folder4/file://../../../../etc/passwd

When processed by the vulnerable application, the validation function treats folder1 through folder4 and the file: segment as positive depth markers, keeping the overall state positive. After normalization, the padding folders are eliminated by the traversal sequences, leaving only the relative traversal to /etc/passwd. The application subsequently executes the file operation against the system file rather than a subdirectory of the volume root, exposing the target content to the administrative panel.

Security Impact Assessment

The concrete security impact of this vulnerability depends on the specific actions performed by the downstream components that call the local filesystem driver. If the path traversal is triggered within a read context, such as downloading or indexing assets, the attacker can read arbitrary files from the local filesystem that are readable by the PHP process. This includes administrative configurations, environmental files, database credentials, and system credentials.

In write contexts, such as renaming or moving files, the vulnerability could allow an attacker to overwrite system files or write files to writable web directories. An attacker could potentially upload a PHP web shell into the public web root by traversing out of the asset storage folder and writing into a publicly accessible directory. This turns the path traversal bypass into an arbitrary code execution vector.

This vulnerability is tracked under GitHub Security Advisory GHSA-7HXC-F267-H5Q7. The vendor has assigned a low-severity rating due to the prerequisite requirement of administrative privileges. However, in environments utilizing multi-tenant setups or delegated administration, this flaw represents an escalation path that compromises the host server. The estimated CVSS score is 4.9, with the vector string CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:L/I:L/A:N reflecting the high privilege requirement.

Detection & Remediation

Remediation requires upgrading Craft CMS core to a secure version. The development team has released patches for the affected branches. Organizations running Craft CMS 4.x must update to version 4.18.2 or later. Organizations running Craft CMS 5.x must update to version 5.10.6 or later. Upgrades are applied through PHP Composer by running the core package update command:

composer update craftcms/cms

To detect potential exploitation attempts, security operations teams should analyze server request logs and application error logs. Look for instances of administrative actions containing protocol indicators like file:// or file%3A%2F%2F in combination with directory traversal patterns like ../. Additionally, monitor application crash logs for craft\errors\FsException which indicate that a path containment validation failed.

System administrators should implement system-level hardening to limit the impact of directory traversal vulnerabilities. Ensure the web server and PHP-FPM processes run under a low-privileged dedicated user account. This user must be restricted from reading critical system files like /etc/passwd or accessing other directories outside of the active web root. Implementing restricted PHP configurations such as setting open_basedir can also prevent the PHP engine from accessing files outside specified paths.

Official Patches

Craft CMSPatch commit resolving GHSA-7HXC-F267-H5Q7 in Craft CMS 4.x
Craft CMSPatch commit resolving GHSA-7HXC-F267-H5Q7 in Craft CMS 5.x

Fix Analysis (2)

Technical Appendix

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

Affected Systems

Craft CMS 4.xCraft CMS 5.x

Affected Versions Detail

Product
Affected Versions
Fixed Version
Craft CMS
Craft CMS
>= 4.0.0, < 4.18.24.18.2
Craft CMS
Craft CMS
>= 5.0.0, < 5.10.65.10.6
AttributeDetail
CWE IDCWE-22
Attack VectorNetwork
CVSS Score4.9
Exploit StatusPoC available
CISA KEVNot Listed
Ransomware UseNo

MITRE ATT&CK Mapping

T1083File and Directory Discovery
Discovery
T1005Data from Local System
Collection
T1556Modify Authentication Process
Defense Evasion
CWE-22
Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

The software uses external input to construct a pathname that should be within a restricted directory, but it does not properly neutralize sequences such as '..' that can resolve to a location outside of the restricted directory.

Known Exploits & Detection

GitHub AdvisoryAdvisory containing conceptual proof of concept details for path containment bypass

Vulnerability Timeline

Security advisory published
2026-06-13
Patch released in Craft CMS 4.18.2 and 5.10.6
2026-06-13

References & Sources

  • [1]GitHub Advisory Database: GHSA-7HXC-F267-H5Q7
  • [2]Craft 4.x Fix Commit
  • [3]Craft 5.x Fix Commit
  • [4]Craft CMS 4.18.2 Release Notes
  • [5]Craft CMS 5.10.6 Release Notes

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

•18 minutes ago•CVE-2026-105749
6.5

CVE-2026-105749: Unbounded Table Attributes in Docling Backends Leads to Resource Exhaustion

An uncontrolled resource consumption vulnerability exists in the Docling document conversion library. Maliciously structured HTML, JATS, ODS, or BoxNote inputs containing table cells with excessively large 'rowspan' or 'colspan' attribute values trigger algorithmic complexity conditions. This allows unauthenticated remote attackers to initiate resource exhaustion states, crashing or hanging the target document processing pipeline while bypassing configured timeouts.

Amit Schendel
Amit Schendel
0 views•6 min read
•about 1 hour ago•CVE-2026-105748
4.3

CVE-2026-105748: Local File Inclusion and Arbitrary File Disclosure in Docling Document Parser

A Local File Inclusion (LFI) and Arbitrary File Disclosure vulnerability exists in Docling and Docling Slim versions >= 2.16.0 up to 2.131.0. When parsing serialized DoclingDocument structures using the JSON input format, the backend fails to restrict image URI schemes, allowing remote attackers to retrieve local files and verify path existence on the host system during embedded document export.

Amit Schendel
Amit Schendel
3 views•5 min read
•about 2 hours ago•CVE-2026-105744
7.5

CVE-2026-105744: Arbitrary File Read and Remote Code Execution in Docling Tectonic Engine

Docling, a tool for parsing and processing diverse document formats, is vulnerable to arbitrary file read, arbitrary file write, and potential remote code execution (RCE) in versions 2.94.0 through 2.131.0. The vulnerability occurs when applications configure Docling to use the Tectonic engine for rendering TikZ diagrams into images. Because the compilation did not restrict hazardous TeX primitives or sandbox the environment, an attacker can supply crafted documents containing malicious TikZ definitions to access or modify local files and execute arbitrary commands under the privileges of the processing application.

Amit Schendel
Amit Schendel
4 views•7 min read
•about 3 hours ago•CVE-2026-105743
4.0

CVE-2026-105743: Server-Side Request Forgery Guard Bypass in Docling Document Conversion Engine

An SSRF guard bypass vulnerability in the Docling document conversion engine allows unauthenticated attackers to bypass internal IP access controls. The vulnerability exists due to a DNS rebinding Time-of-Check Time-of-Use (TOCTOU) condition, URL authority parsing inconsistencies, and unvalidated network requests triggered during headless browser page rendering.

Amit Schendel
Amit Schendel
4 views•6 min read
•about 4 hours ago•CVE-2026-105742
3.7

CVE-2026-105742: Sensitive Custom Header Leakage in Docling Image Resource Loader

A technical analysis of CVE-2026-105742 (GHSA-p3fw-7699-7926), a sensitive information disclosure vulnerability in the Docling document processing library. Vulnerable versions of Docling indiscriminately forward custom HTTP headers, such as authentication tokens, to arbitrary third-party origins and during cross-origin redirects while fetching remote image assets from untrusted HTML and EPUB documents.

Alon Barad
Alon Barad
5 views•6 min read
•about 5 hours ago•CVE-2026-106121
4.9

CVE-2026-106121: Denial of Service via Infinite Loop in RabbitMQ Java Client JSON Parser

CVE-2026-106121 is a Denial of Service (DoS) vulnerability in the RabbitMQ Java Client library (amqp-client) affecting versions prior to 5.37.0. The vulnerability resides in the legacy, custom JSON-RPC parsing class com.rabbitmq.tools.json.JSONReader. When parsing malformed or truncated payloads ending within a quoted string or single-line comment, the parser's scanner enters an infinite loop. This occurs because the loop lacks an exit condition for the end-of-input sentinel character returned by the iterator, leading to either CPU exhaustion or a JVM crash from an OutOfMemoryError.

Amit Schendel
Amit Schendel
7 views•6 min read