
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 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.
User-AgentDie 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.
POST /index.php/shop/checkout HTTP/1.1
Host: TARGET
User-Agent: <script>alert(document.domain)</script>
Content-Type: application/x-www-form-urlencoded
phcheckouttac=1&task=checkout.order&option=com_phocacart&return=&<CSRF_TOKEN>=1
Ergebnis: Bestellung erstellt. Die Datenbank speichert user_agent = '<script>alert(document.domain)</script>'.

Der Administrator navigiert zu Komponenten → Phoca Cart → Bestellungen. Die injizierte Bestellung erscheint in der Liste. XSS wird in dieser Phase noch nicht ausgelöst.

Wenn der Administrator auf die Bestellung klickt, um die Bearbeitungsansicht zu öffnen, wird der gespeicherte user_agent über itemText() unescaped gerendert. JavaScript wird sofort ausgeführt.
Trigger-URL:
/administrator/index.php?option=com_phocacart&view=phocacartorder&layout=edit&id=<ORDER_ID>
