
Gespeichertes XSS über User-Agent in der Admin-Bestellansicht in PhocaCart
PhocaCart ≤ 6.1.7 — Nicht authentifizierter Angreifer speichert XSS-Payload über den Checkout. Wird im Admin-Browser-Kontext ausgeführt
PhocaCart 6.1.7 für Joomla speichert den rohen HTTP-User-Agent-Header aus Checkout-Anfragen in der Bestell-Datenbanktabelle, wenn die Konfigurationsoption store_user_agent aktiviert ist. Der gespeicherte Wert wird anschließend ohne HTML-Kodierung über itemText() in Adminview.php in die Bestellbearbeitungsansicht des Administrators gerendert.
Ein nicht authentifizierter Angreifer kann eine Bestellung mit einem manipulierten User-Agent aufgeben, der einen JavaScript-Payload enthält. Wenn ein Administrator die Bestellung im Backend öffnet, wird der Payload im Admin-Browser-Kontext ausgeführt — was Session-Hijacking, den Diebstahl von Anmeldedaten oder unautorisierte administrative Aktionen ermöglicht.
Die Schwachstelle erfordert, dass store_user_agent = 1 (nicht standardmäßig) aktiviert ist. Da diese Option eine bewusste Administrator-Entscheidung zur Erfassung von Browserstatistiken darstellt, sind betroffene Shops solche, in denen der Shopbetreiber die Funktion aktiviert hat — was die Ausnutzung aus Sicht des Angreifers völlig lautlos macht.
| KOMPONENTE | VERWUNDBAR | GETESTET AUF | BEHOBEN |
|---|---|---|---|
| PhocaCart (com_phocacart) | 5.0.0 – 6.1.7 | Joomla 5.4.7 + PhocaCart 6.1.7 + MariaDB 10.6 | 6.1.8 |
Typ: Gespeichertes XSS (CWE-79) — auf den Administrator abzielend
Erforderliche Authentifizierung: Keine zum Injizieren. Administrator zum Auslösen
CSRF-Token erforderlich: Ja (standardmäßiges Joomla-CSRF-Token für den Checkout erforderlich)
Datei: administrator/components/com_phocacart/libraries/Phoca/Render/Adminview.php:382
Wenn store_user_agent = 1 ist, gibt die Methode PhocacartUtils::getUserAgent() $_SERVER['HTTP_USER_AGENT'] ohne jegliche Bereinigung zurück. Diese rohe Zeichenkette wird in #__phocacart_orders gespeichert (auf 200 Zeichen gekürzt — nicht ausreichend, um XSS zu verhindern). Wenn ein Administrator die Bestellung im Backend anzeigt, fügt itemText() den gespeicherten Wert ohne Aufruf von htmlspecialchars() direkt in die HTML-Antwort ein.
Datenfluss:
Attacker sends checkout request:
User-Agent: <script>alert(document.domain)</script>
utils.php:334 PhocacartUtils::getUserAgent()
└─ return (string) $_SERVER['HTTP_USER_AGENT'] // raw, no sanitization
order.php:413 $d['user_agent'] = substr($user_agent, 0, 200)
└─ INSERT INTO #__phocacart_orders (user_agent) VALUES ('<script>...</script>')
Admin opens order in backend:
edit.php:84 echo $r->itemText($this->itemcommon->user_agent, ...)
Adminview.php:382 '<div class="controls >' . $item . '</div>'
// → NO htmlspecialchars()
→ Browser renders: <div><script>alert(document.domain)</script></div>
→ XSS fires in administrator's browser
ORDER.PHP — SPEICHERPHASE (VERWUNDBARE QUELLE)
administrator/components/com_phocacart/libraries/phocacart/order/order.php:424
$user_agent = PhocacartUtils::getUserAgent(); // reads $_SERVER['HTTP_USER_AGENT'] raw
$d['user_agent'] = substr($user_agent, 0, 200); // stored in DB unfiltered
ADMINVIEW.PHP:382 — RENDER-PHASE (VERWUNDBARER SINK)
// No htmlspecialchars() applied:
$output .= ' <div class="controls ' . $class . '">' . $item . '</div>' . "\n";
Aufgerufen aus administrator/components/com_phocacart/views/phocacartorder/tmpl/edit.php:84:
echo $r->itemText($this->itemcommon->user_agent, Text::_('COM_PHOCACART_USER_AGENT'), '', 'user_agent');
Die Funktion itemText() übergibt $item (den gespeicherten user_agent-Wert) ohne Kodierung direkt in die HTML-Ausgabe und macht sie damit zum primären Sink. Eine Korrektur auf Sink-Ebene schützt alle Aufrufer von itemText().
Der Angriff erfordert das vollständige Durchlaufen des Checkout-Prozesses mit einem bösartigen User-Agent-Header. Das CSRF-Token muss zuerst erlangt werden, da der Checkout-Controller von Joomla es validiert.
Navigieren Sie im Joomla-Admin zu Komponenten → Phoca Cart → Optionen → Registerkarte Haupt → Statistik-Optionen. Setzen Sie User-Agent-Informationen speichern = Ja und speichern Sie.

Der Angreifer besucht das Shop-Frontend, um ein gültiges Joomla-CSRF-Token zu extrahieren, das vom Checkout-Controller benötigt wird. Das Token erscheint im HTML-Quelltext oder in der JavaScript-Konfiguration einer beliebigen Shop-Seite.

Der Angreifer legt ein Produkt über den AJAX-Checkout-Endpunkt mit einem harmlosen User-Agent in den Warenkorb. Dadurch wechselt die Checkout-Sitzung in den nächsten Status.

Der Angreifer übermittelt Rechnungsinformationen, um die Checkout-Zustandsmaschine voranzutreiben.

Der Angreifer wählt eine Versandmethode, um zur Zahlung fortzufahren.

Der Angreifer wählt eine Zahlungsmethode (z. B. Nachnahme).

Kritischer Injektionsschritt. Der Angreifer gibt die endgültige Bestellung über task=checkout.order auf, wobei der User-Agent-Header auf den XSS-Payload gesetzt ist. Die Aufgabe checkout.order liest den rohen HTTP_USER_AGENT und speichert ihn unescaped in #__phocacart_orders.user_agent.