GitHub Advisoryadvisory · Packagist
GHSA-mf2p-wjp4-99pq REDAXO: Stored XSS via Unescaped Media Manager Type Name in `mediaIsInUse()`
MEDIUM
Official page ↗
- Aliases
- CVE-2026-63001
- Ecosystem
- Packagist
- Packages
- redaxo/source
- Severity
- Moderate
- CVSS vector
- CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:L/I:L/A:N
- Weaknesses
- CWE-79
- Reviewed
- 2026-09-23
Affected packages
• Packagist redaxo/source: < 5.21.2 → fixed in 5.21.2
Description
Summary
A stored cross-site scripting (XSS) vulnerability exists in REDAXO CMS 5.x. When an administrator attempts to delete a media file that is referenced by a Media Manager effect, the warning message rendered in the backend includes the type's `name` field without HTML escaping. An attacker with access to the Media Manager addon can store an XSS payload as a type name; the payload executes in the browser of any administrator who subsequently tries to delete a media file linked to that type's effects. This can lead to session hijacking and full backend account takeover.
---
Details
File: `redaxo/src/addons/media_manager/lib/media_manager.php`
Function: `mediaIsInUse()` — registered on the `MEDIA_IS_IN_USE` extension point in `boot.php`
When `rex_media_service::deleteMedia()` is called, it invokes `rex_mediapool::mediaIsInUse($filename)`, which fires the `MEDIA_IS_IN_USE` extension point. The media_manager addon's handler queries all effects whose `parameters` JSON contains the filename, then constructs an HTML anchor with the type name inserted verbatim:
```php
// media_manager.php ~line 457 ← VULNERABLE
$message = ''
. rex_i18n::msg('media_manager') . ' '
. rex_i18n::msg('media_manager_effect_name') . ': '
. (string) $sql->getValue('name') // ← NO rex_escape() call
. '';
```
The returned `$message` string is concatenated into the exception message thrown by `deleteMedia()` and rendered by `rex_view::error()` as raw HTML.
Contrast with the correct pattern used elsewhere in the same addon:
```php
// types.php line 91 ← CORRECT
$name = '' . rex_escape($list->getValue('name')) . '';
```
Input validation gap: `types.php` line 200 validates the type name with the rule `NOT_MATCH '{[/\\]}'`, which blocks `{`, `/`, and `\` but permits ``, `"`, `'`, and `&` — all characters required to inject HTML.
---
PoC
Test environment: REDAXO 5.x running at `http://localhost/`
Account required: Any REDAXO backend administrator
Test credentials: username `admin` / password `Admin12345!`
Step 1 — Seed test data directly into the database (single CMD command)
```cmd
docker exec -i 34--core-5x-redaxo-1 php -r "$p=new PDO('mysql:host=db;dbname=redaxo','redaxo','redaxo');$p->exec(\"INSERT IGNORE INTO rex_media(category_id,attributes,filetype,filename,originalname,filesize,width,height,title,createdate,createuser,updatedate,updateuser) VALUES(0,'','image/jpeg','xss_test.jpg','xss_test.jpg',284,1,1,'XSS Test',NOW(),'admin',NOW(),'admin')\");$tid=$p->query(\"SELECT id FROM rex_media_manager_type WHERE name=''\")->fetchColumn();if(!$tid){$p->prepare(\"INSERT INTO rex_media_manager_type(status,name,description,createdate,createuser,updatedate,updateuser) VALUES(1,?,'poc',NOW(),'admin',NOW(),'admin')\")->execute(['']);$tid=$p->lastInsertId();}$p->prepare(\"INSERT IGNORE INTO rex_media_manager_type_effect(type_id,effect,parameters,priority,createdate,createuser,updatedate,updateuser) VALUES(?,'watermark',?,1,NOW(),'admin',NOW(),'admin')\")->execute([$tid,json_encode(['rex_effect_watermark'=>['watermark_image'=>'xss_test.jpg']])]);echo \"OK type_id=$tid\n\";"
```
Step 2 — Place a 1×1 JPEG in the media directory
```cmd
docker exec 34--core-5x-redaxo-1 sh -c "printf '\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00\xff\xdb\x00C\x00\x08\x06\x06\x07\x06\x05\x08\x07\x07\x07\t\t\x08\n\x0c\x14\r\x0c\x0b\x0b\x0c\x19\x12\x13\x0f\x14\x1d\x1a\x1f\x1e\x1d\x1a\x1c\x1c $.\' \",#\x1c\x1c(7),01444\x1f\x27=82\x1b\x1b123\x1e4\x1c\x1f\xff\xc0\x00\x0b\x08\x00\x01\x00\x01\x01\x01\x11\x00\xff\xc4\x00\x1f\x00\x00\x01\x05\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\xff\xda\x00\x08\x01\x01\x00\x00?\x00\xf5\x00\xff\xd9' > /var/www/html/media/xss_test.jpg"
```
Step 3 — Login to the backend
Open a browser and navigate to:
```
http://localhost/redaxo/index.php
```
Login with: admin / Admin12345!
Step 4 — Trigger the XSS
Navigate to the media file detail page:
```
http://localhost/redaxo/index.php?page=mediapool/media&file_id=1
```
Click the Delete button. REDAXO checks whether the file is in use, finds the Watermark effect whose `parameters` JSON references `xss_test.jpg`, and renders the type name in the warning HTML without escaping.
Result: The browser executes `` and an alert dialog showing the current domain appears immediately.
---
Impact
Vulnerability type: Stored Cross-Site Scripting (Stored XSS)
Who is impacted:
Any backend administrator who attempts to delete a media file that is referenced by a Media Manager effect. A malicious administrator (or an attacker who has compromised any admin account) can pre-plant a payload in a type name. All other administrators who later try to delete affected media files will have the payload executed in their browser sessions.
Exploitability:
• Privilege required to plant: Administrator (access to Media Manager addon)
• Privilege required to trigger: Administrator (access to Mediapool)
• User interaction required: Victim must click "Delete" on a media file
Realistic attack scenarios:
• Session cookie theft via `document.cookie` exfiltration (leads to full account takeover)
• Credential harvesting by dynamically replacing the login form
• CSRF-token extraction to perform authenticated actions on behalf of the victim
---
Fix
Apply `rex_escape()` to the type name before concatenating it into the HTML anchor:
```php
// media_manager.php — apply rex_escape() to the name value
$message = ''
. rex_i18n::msg('media_manager') . ' '
. rex_i18n::msg('media_manager_effect_name') . ': '
. rex_escape((string) $sql->getValue('name')) // ← ADD rex_escape()
. '';
```
Related
Alias · CVE (1)
- CVE-2026-63001 REDAXO is a PHP-based content management system. vulnerability
Weakness · CWE (1)
- CWE-79 Improper Neutralization of Input During Web Page Generation weakness