
PoC-Repository für CVE-2025-68147: Stored Cross-Site Scripting (XSS) in OpenSourcePOS. Die Schwachstelle ermöglicht eine Privilegienausweitung durch bösartige JavaScript-Injektion im Store-Config-Modul. Enthält Payload-Details und Patch-Verifizierung (v3.4.0). Sicherheitsforscher: Aditya Singh (Nixon-H).
| Metadaten | Details |
|---|
| CVE-ID | CVE-2025-68147 |
| Schweregrad | Hoch CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:H/I:H/A:N |
| Schwachstellentyp | Stored Cross-Site Scripting (CWE-79) |
| Betroffene Versionen | OpenSourcePOS v3.4.0, v3.4.1 |
| Gepatchte Version | v3.4.2 |
| Verwundbare Komponente | Store Configuration Module (Return Policy-Feld) |
| Melder | Aditya Singh (Nixon-H) |
Eine Stored Cross-Site Scripting (XSS)-Schwachstelle wurde im Store Configuration-Modul von OpenSourcePOS entdeckt. Die Anwendung säuberte die vom Benutzer bereitgestellte Eingabe im Feld "Return Policy" nicht ordnungsgemäß, bevor sie in der Datenbanktabelle ospos_app_config gespeichert wurde.
Dieser Fehler erlaubte es einem authentifizierten Angreifer mit Konfigurationsrechten (oder einem Angreifer, der eine separate CSRF-Kette ausnutzt), beliebige JavaScript-Payloads zu injizieren. Da die "Rückgaberegelung" auf jedem Verkaufsbeleg dynamisch gerendert wird, wird die injizierte Payload automatisch im Browser jedes Benutzers ausgeführt – einschließlich Kassierern mit niedrigen Rechten, anderen Administratoren oder Kunden – sobald ein Beleg generiert oder angesehen wird.
Die Schwachstelle befindet sich in der Beleg-Ansichtsvorlage: app/Views/sales/receipt_default.php.
Die Anwendung ruft die Zeichenkette der "Rückgaberegelung" aus dem globalen Konfigurationsarray ($this->config['return_policy']) ab und bereitet sie zur Anzeige vor.
nl2br(), um Zeilenumbrüche in HTML-Zeilenumbrüche (<br>) umzuwandeln.nl2br() säubert keine HTML-Sonderzeichen. Es lässt Tags wie <script>, `` und onload-Attribute vollständig intakt.Verwundbarer Code (vor dem Patch):
<div id="sale_return_policy">
<?php echo nl2br($this->config['return_policy']); ?>
</div>
Wenn ein Administrator die Konfiguration speichert, wird die Payload roh in der Datenbank gespeichert.
ospos_app_configreturn_policyRichtlinientext... <script>alert('XSS')</script>Da es keine Eingabebereinigung auf der Controllerseite (Config.php) und keine Ausgabe-Escaping auf der View-Seite (receipt_default.php) gibt, ist die Anwendung anfällig für Stored XSS.
Der Angriff zielt auf das Store Configuration-Panel ab, wirkt sich jedoch auf das Sales/Receipt-Modul aus.
http://[ZIEL]/config (POST-Anfrage zum Speichern der Konfiguration)http://[ZIEL]/sales/receipt/[VERKAUFS_ID]Schritt 1: Die Injektion Wir haben uns als Administrator angemeldet und zu Store Configuration -> General navigiert. Im Textfeld "Return Policy" haben wir die folgende spezifische Payload injiziert:
Standard Return Policy: No Refunds.
<script>alert('XSS_BY_NIXON_SUCCESSFUL')</script>
Schritt 2: Persistenz
Nach dem Klicken auf "Submit" sendete die Anwendung eine POST-Anfrage an /config/save. Die Payload wurde erfolgreich in die Datenbank übernommen.
Schritt 3: Der Auslöser Um die Auswirkungen auf andere Benutzer zu überprüfen:
http://localhost/sales/receipt/1). Der Browser parst das return_policy-Div, trifft auf das <script>-Tag und führt sofort das JavaScript aus.Beobachtetes Ergebnis:
Ein Browser-Alarmfeld erschien mit der Nachricht: XSS_BY_NIXON_SUCCESSFUL.
Screenshot 1: Der ausgelöste Alert
Screenshot 2: Payload in der Konfiguration
🎥 Videodemonstration: Klicken zum Herunterladen / Ansehen des PoC-Videos
Hierbei handelt es sich um eine Schwachstelle mit geändertem Bereich (S:C), da der Angriff auf dem Server gespeichert wird, aber im Browser-Kontext des Opfers ausgeführt wird.
/sales/receipt/105). Das Skript wird still ausgeführt und sendet document.cookie (mit der ospos_session-ID) an den Server des Angreifers./employees/save zu senden.hacker / password123) wird sofort im Hintergrund erstellt. Das Opfer sieht nur den Beleg, während der Angreifer eine permanente Hintertür erhält.Die Schwachstelle wurde in OpenSourcePOS v3.4.2 behoben.
Der Betreuer hat einen Patch angewendet, der eine kontextbezogene Ausgabe-Kodierung implementiert. Der Konfigurationswert wird jetzt mit der globalen esc()-Hilfsfunktion von CodeIgniter umschlossen, bevor er an nl2br() übergeben wird.
Der Patch (Commit 22297a):
<div id="sale_return_policy">
<?php echo nl2br(esc($this->config['return_policy'])); ?>
</div>
Überprüfung: Nach dem Upgrade auf v3.4.2 wird dieselbe Payload als harmloser Text dargestellt:
Standard Return Policy: No Refunds. <script>alert('XSS_BY_NIXON_SUCCESSFUL')</script>
22297a) und vom Forscher verifiziert.