
Repositorio PoC para CVE-2025-68147: Cross-Site Scripting (XSS) Almacenado en OpenSourcePOS. La vulnerabilidad permite escalada de privilegios mediante inyección de JavaScript malicioso en el módulo Store Config. Incluye detalles del payload y verificación del parche (v3.4.0). Investigador de Seguridad: Aditya Singh (Nixon-H).
| Metadatos | Detalles |
|---|---|
| ID CVE | CVE-2025-68147 |
| Gravedad | Alta CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:H/I:H/A:N |
| Tipo de Vulnerabilidad | Cross-Site Scripting Almacenado (CWE-79) |
| Versiones Afectadas | OpenSourcePOS v3.4.0, v3.4.1 |
| Versión Parcheada | v3.4.2 |
| Componente Vulnerable | Módulo de Configuración de Tienda (campo Política de Devolución) |
| Reportado por | Aditya Singh (Nixon-H) |
Se descubrió una vulnerabilidad de Cross-Site Scripting (XSS) Almacenado en el módulo de Configuración de Tienda de OpenSourcePOS. La aplicación no sanitizaba adecuadamente la entrada proporcionada por el usuario en el campo "Política de Devolución" antes de almacenarla en la tabla de base de datos ospos_app_config.
Esta falla permitía que un atacante autenticado con privilegios de configuración (o un atacante que explotara una cadena CSRF separada) inyectara cargas útiles arbitrarias de JavaScript. Debido a que la "Política de Devolución" se renderiza dinámicamente en cada recibo de venta, la carga útil inyectada se ejecuta automáticamente en el navegador de cualquier usuario —incluyendo cajeros con pocos privilegios, otros administradores o clientes— cada vez que se genera o visualiza un recibo.
La vulnerabilidad reside en la plantilla de vista de recibo: app/Views/sales/receipt_default.php.
La aplicación recupera la cadena "Política de Devolución" del arreglo de configuración global ($this->config['return_policy']) y la prepara para mostrarla.
nl2br() para convertir saltos de línea en etiquetas HTML <br>.nl2br() no sanitiza los caracteres especiales HTML. Deja intactas etiquetas como <script>, `` y atributos onload.Código Vulnerable (Antes del Parche):
<div id="sale_return_policy">
<?php echo nl2br($this->config['return_policy']); ?>
</div>
Cuando un administrador guarda la configuración, la carga útil se almacena en crudo en la base de datos.
ospos_app_configreturn_policyPolicy Text... <script>alert('XSS')</script>Debido a que no hay sanitización de entrada en el lado del controlador (Config.php) ni escapado de salida en el lado de la vista (receipt_default.php), la aplicación es vulnerable a XSS Almacenado.
El ataque apunta al panel de Configuración de Tienda pero impacta en el módulo de Ventas/Recibos.
http://[TARGET]/config (solicitud POST para guardar configuración)http://[TARGET]/sales/receipt/[SALE_ID]Paso 1: La Inyección Iniciamos sesión como Administrador y navegamos a Configuración de Tienda -> General. En el área de texto "Política de Devolución", inyectamos la siguiente carga útil específica:
Standard Return Policy: No Refunds.
<script>alert('XSS_BY_NIXON_SUCCESSFUL')</script>
Paso 2: Persistencia
Al hacer clic en "Enviar", la aplicación envió una solicitud POST a /config/save. La carga útil se almacenó exitosamente en la base de datos.
Paso 3: La Activación Para verificar el impacto en otros usuarios:
http://localhost/sales/receipt/1). El navegador analiza el div return_policy, encuentra la etiqueta <script> e inmediatamente ejecuta el JavaScript.Resultado Observado:
Apareció una ventana de alerta en el navegador con el mensaje: XSS_BY_NIXON_SUCCESSFUL.
Captura de pantalla 1: La Alerta Activada
Captura de pantalla 2: Carga Útil en la Configuración
🎥 Demostración en Video: Haga clic para Descargar / Ver el Video de la PoC
Esta es una vulnerabilidad de Cambio de Ámbito (S:C) porque el ataque se almacena en el servidor pero se ejecuta en el contexto del navegador de la víctima.
/sales/receipt/105). El script se ejecuta silenciosamente, enviando document.cookie (que contiene el ID de sesión ospos_session) al servidor del atacante./employees/save.hacker / password123). La víctima no ve nada más que el recibo, mientras el atacante obtiene una puerta trasera permanente.La vulnerabilidad se corrigió en OpenSourcePOS v3.4.2.
El mantenedor aplicó un parche que implementa Codificación de Salida Sensible al Contexto. El valor de configuración ahora está envuelto en la función auxiliar global esc() de CodeIgniter antes de pasarse a nl2br().
El Parche (Commit 22297a):
<div id="sale_return_policy">
<?php echo nl2br(esc($this->config['return_policy'])); ?>
</div>
Verificación: Después de actualizar a v3.4.2, la misma carga útil se renderiza como texto inofensivo:
Standard Return Policy: No Refunds. <script>alert('XSS_BY_NIXON_SUCCESSFUL')</script>
22297a) y verificado por el investigador.