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

CVE-2026-75592: Kirby CMS Path Traversal Vulnerability

CVE-2026-75592 is a path traversal vulnerability in Kirby CMS that allows attackers to access files in sibling directories through incomplete filesystem checks. This article covers technical details, affected versions, and mitigation.

Published:

CVE-2026-75592 Overview

CVE-2026-75592 is a path containment bypass in Kirby, an open-source PHP content management system. The flaw resides in Kirby's media handler, where Kirby\Filesystem\Dir::realpath() and Kirby\Filesystem\F::realpath() performed a string-prefix comparison without enforcing a directory separator boundary. A remote attacker can invoke Kirby\Cms\Media::thumb() to reach a PHP-readable sibling directory that shares the intended root's name prefix, such as /var/www/site2 next to /var/www/site. When that directory contains a valid .json thumbnail job file, the attacker can generate and access thumbnails from images in the sibling location and delete the job file during processing. This weakness maps to CWE-22 (Path Traversal).

Critical Impact

Remote unauthenticated attackers can access image content and delete thumbnail job files in adjacent sites, exposing staging environments, backups, or co-hosted internal sites.

Affected Products

  • Kirby CMS versions prior to 4.9.5 (4.x release line)
  • Kirby CMS versions prior to 5.5.2 (5.x release line)
  • Deployments where sibling directories share a name prefix with the Kirby media root

Discovery Timeline

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

Technical Details for CVE-2026-75592

Vulnerability Analysis

The vulnerability stems from an incomplete filesystem containment check in Kirby's realpath helpers. Both Dir::realpath() in src/Filesystem/Dir.php and F::realpath() in src/Filesystem/F.php verified containment with substr($realpath, 0, strlen($parent)) !== $parent. This comparison accepts any path that begins with the parent string, including sibling paths that share the same name prefix. A parent of /var/www/site therefore matches /var/www/site2, /var/www/site-backup, and similar directories.

The issue becomes exploitable through Kirby\Cms\Media::thumb(). The method concatenates a caller-supplied $filename to the validated $root and then reads a job file at $root . '/.jobs/' . $filename . '.json'. Because the root check accepted sibling directories, an attacker can steer processing toward image files in an unrelated directory that Kirby was never intended to serve.

Root Cause

The root cause is a missing DIRECTORY_SEPARATOR boundary in the containment check. Prefix matching without a trailing separator conflates a directory with any sibling whose name starts with the same characters. The Media::thumb() handler also did not require $filename to be a plain basename, allowing untrusted input to influence file paths appended to the trusted root.

Attack Vector

Exploitation is remote and unauthenticated over the network. An attacker crafts a request to the Kirby media route referencing a filename for which a valid .json job file exists inside a sibling directory that shares the media root's name prefix. Kirby resolves the sibling path, generates a thumbnail from an image in that directory, returns it to the attacker, and deletes the job file as part of processing.

php
// Patch: src/Filesystem/Dir.php – enforce separator boundary in realpath()
// require a path separator boundary so that
// a sibling directory sharing the same name prefix
// (e.g. `/site2` for the parent `/site`)
// cannot pass the containment check
$parent = rtrim($parent, '/\\');

if (
    $realpath !== $parent &&
    str_starts_with($realpath, $parent . DIRECTORY_SEPARATOR) === false
) {
    throw new Exception('The directory is not within the parent directory');
}
// Source: https://github.com/getkirby/kirby/commit/2b6fab950bc89d505ea89576bf71c8de614cc3b2
php
// Patch: src/Cms/Media.php – reject non-basename filenames in Media::thumb()
// $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: https://github.com/getkirby/kirby/commit/e0dca5f709adc21b36f5549df2c0619bc59da56c

Detection Methods for CVE-2026-75592

Indicators of Compromise

  • Web server access logs showing requests to /media/ paths that resolve to files outside the intended Kirby site root.
  • Unexpected deletions of .json files under .jobs/ directories of adjacent sites on the same host.
  • HTTP 200 responses returning thumbnails whose source image resides in a sibling directory such as site2 when only site is served.

Detection Strategies

  • Inspect Kirby application logs and PHP error output for NotFoundException: The thumbnail configuration could not be found bursts, which can indicate probing.
  • Correlate media URL patterns with filesystem access events to flag reads that cross the configured site root boundary.
  • Review deployed Kirby versions across all hosts and alert on any instance below 4.9.5 or 5.5.2.

Monitoring Recommendations

  • Enable filesystem auditing on directories adjacent to Kirby media roots to capture read and unlink operations by the PHP process user.
  • Track outbound response payload hashes from media endpoints to identify content served from unexpected paths.
  • Monitor the Kirby GitHub Security Advisory GHSA-6j4c-mgqr-qv76 for updated guidance.

How to Mitigate CVE-2026-75592

Immediate Actions Required

  • Upgrade Kirby to version 4.9.5 on the 4.x line or version 5.5.2 on the 5.x line.
  • Inventory shared hosts and identify Kirby site roots that share a name prefix with adjacent directories, such as site and site2.
  • Audit .jobs/ directories across co-hosted sites for missing or unexpectedly deleted .json files.

Patch Information

The fix lands in two commits. Commit 2b6fab9 tightens Dir::realpath() and F::realpath() to require a DIRECTORY_SEPARATOR boundary using str_starts_with($realpath, $parent . DIRECTORY_SEPARATOR). Commit e0dca5f adds a basename check in Media::thumb(), rejecting $filename values that contain path information or equal . or ... Both fixes ship in Kirby 4.9.5 and 5.5.2.

Workarounds

  • Rename co-hosted site directories so that no sibling shares a name prefix with a Kirby media root (for example, rename site2 to staging-alt).
  • Restrict PHP process filesystem access using open_basedir or systemd ReadOnlyPaths and InaccessiblePaths to prevent reads outside the intended site root.
  • Isolate each Kirby installation under a separate operating system user or container so the web process cannot read adjacent site content.
bash
# php.ini per-site hardening to constrain filesystem access
[PATH=/var/www/site]
open_basedir = "/var/www/site/:/tmp/"

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.