Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-75594

CVE-2026-75594: Kirby CMS Path Traversal Vulnerability

CVE-2026-75594 is a path traversal vulnerability in Kirby CMS that allows attackers to access files outside intended directories and disclose sensitive information. This article covers technical details, affected versions, and remediation.

Published:

CVE-2026-75594 Overview

CVE-2026-75594 is a path traversal vulnerability in Kirby, an open-source content management system written in PHP. The flaw resides in the media handler Kirby\Cms\Media::thumb() in src/Cms/Media.php, which appends an attacker-controlled filename to a validated parent media directory without stripping path separators. On nginx, PHP's built-in server, or Apache configured with AllowEncodedSlashes enabled, remote attackers can submit URL-encoded slashes such as %2f in the filename to escape the intended media directory. A related weakness in src/Filesystem/Asset.php accepts ../ sequences outside the intended index root. The issue is fixed in versions 4.9.5 and 5.5.2.

Critical Impact

Unauthenticated remote attackers can probe for arbitrary .json files on disk and, when a valid filename key is present, cause referenced images to be returned and job files to be deleted, leading to information disclosure and integrity impact.

Affected Products

  • Kirby CMS release line 4.x prior to 4.9.5
  • Kirby CMS release line 5.x prior to 5.5.2
  • Deployments on nginx, PHP built-in server, or Apache with AllowEncodedSlashes enabled

Discovery Timeline

  • 2026-08-31 - CVE-2026-75594 published to NVD
  • 2026-09-01 - Last updated in NVD database

Technical Details for CVE-2026-75594

Vulnerability Analysis

The vulnerability is classified as a path traversal weakness [CWE-22]. Kirby's media handler resolves a parent media directory using Dir::realpath($root, $media), which validates that the directory sits within the expected media root. The handler then concatenates the request-supplied filename to that validated root when constructing the thumbnail path ($root . '/' . $filename) and the job file path ($root . '/.jobs/' . $filename . '.json'). Because the filename is appended unmodified, embedded encoded slashes reintroduce directory separators after validation has completed.

When the webserver (nginx, the PHP built-in server, or Apache with AllowEncodedSlashes enabled) forwards %2f decoded into the request path, PHP receives a filename that contains path components. The handler then reads or deletes files outside of the media directory. Response differences between existing and nonexistent thumbnail configurations create an oracle that discloses whether an arbitrary .json file exists on the filesystem.

Root Cause

The root cause is missing filename validation after path canonicalization. The media handler trusted the caller to supply a plain filename but never enforced that constraint. A parallel issue in Asset.php allowed ../ sequences in the file::version path, permitting traversal outside the intended index root.

Attack Vector

A remote unauthenticated attacker crafts a request to the media endpoint containing an encoded slash inside the filename segment. The traversal enables two primitives: existence checks for arbitrary .json files based on differential responses, and retrieval of an image referenced by a valid filename key inside a discovered .json file. Successful exploitation also deletes the corresponding job file, affecting filesystem integrity.

php
			// prevent path traversal
			$root = Dir::realpath($root, $media);

			// $filename is appended unmodified to the validated root
			// to build the thumbnail and job file paths;
			// it must be a plain filename without any path information
			if (
				$filename === '' ||
				$filename === '.' ||
				$filename === '..' ||
				basename($filename) !== $filename
			) {
				throw new InvalidArgumentException();
			}

			$thumb = $root . '/' . $filename;
			$job   = $root . '/.jobs/' . $filename . '.json';

Source: Kirby commit cd7abb6 - fix: Path traversal in Media::thumb()

Detection Methods for CVE-2026-75594

Indicators of Compromise

  • HTTP requests to Kirby media endpoints containing %2f, %2F, %252f, or ..%2f sequences inside the filename component.
  • Access log entries targeting media URLs with .json extensions or path segments referencing directories outside /media.
  • Unexpected deletion of .jobs/*.json files under the Kirby media root.

Detection Strategies

  • Inspect webserver access logs for encoded slash patterns in URIs routed to Kirby's media handler.
  • Alert on requests that produce filesystem reads outside the configured media and content directories.
  • Compare Kirby installation versions against the fixed releases 4.9.5 and 5.5.2 using inventory tooling.

Monitoring Recommendations

  • Enable verbose PHP error logging for InvalidArgumentException events raised by Media::thumb() after patching to observe blocked traversal attempts.
  • Monitor Apache AllowEncodedSlashes configuration state, since the exploit condition requires it to be enabled.
  • Track file integrity for the .jobs directory and the Kirby content tree to detect unexpected deletions.

How to Mitigate CVE-2026-75594

Immediate Actions Required

  • Upgrade Kirby to 4.9.5 on the 4.x branch or 5.5.2 on the 5.x branch.
  • Review Apache configuration and disable AllowEncodedSlashes unless explicitly required by the application.
  • Audit filesystem permissions on .json files adjacent to the Kirby media root to reduce information disclosure exposure.

Patch Information

The fix adds explicit filename validation in Media::thumb() and rejects any input that is empty, ., .., or contains path separators via basename($filename) !== $filename. Additional hardening in src/Filesystem/Asset.php blocks ../ sequences in file::version paths. See the GitHub Security Advisory GHSA-9vx2-j98c-p72w, the Kirby 4.9.5 release notes, and the Kirby 5.5.2 release notes.

Workarounds

  • On Apache, set AllowEncodedSlashes Off at the virtual host level to block decoded %2f traversal.
  • On nginx, add a location rule that rejects requests containing %2f or %2F in the URI before forwarding to PHP-FPM.
  • Restrict access to the /media route via web application firewall rules that block encoded path separators.
bash
# Apache: disable decoded slashes for the Kirby vhost
<VirtualHost *:443>
    ServerName example.com
    AllowEncodedSlashes Off
</VirtualHost>

# nginx: reject encoded slashes in the request URI
if ($request_uri ~* "%2f|%2F") {
    return 400;
}

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.