Resumen

Durante una auditoría de seguridad sobre una aplicación web corporativa, se descubrió un XSS almacenado en el campo "nombre de organización" del perfil de usuario. Este campo se renderizaba sin sanitización en el panel de administración cuando un administrador revisaba los perfiles de usuarios registrados.

Simultáneamente, se identificó que el endpoint de cambio de email (/api/account/update-email) no implementaba protección CSRF. La combinación de ambas vulnerabilidades permitia una cadena de ataque que llevaba al account takeover de cuentas con privilegios de administrador.

Detalles técnicos

Paso 1: XSS almacenado en campo de perfil

El campo "nombre de organización" aceptaba caracteres especiales y el valor se insertaba en el DOM del panel de administración sin escapar:

Payload XSS almacenado
PUT /api/profile HTTP/1.1
Content-Type: application/json

{
  "organization": "<img src=x onerror=eval(atob('BASE64_PAYLOAD'))>"
}

Cuando un administrador accedía al listado de usuarios en /admin/users, el payload se ejecutaba en su contexto de sesión.

Paso 2: CSRF en cambio de email

El endpoint de actualización de email no validaba ningún token CSRF ni comprobaba la cabecera Origin:

Request sin protección CSRF
POST /api/account/update-email HTTP/1.1
Content-Type: application/json
Cookie: session=[ADMIN_SESSION]

{
  "new_email": "attacker@evil.com"
}

→ 200 OK — Email actualizado sin verificación adicional

Paso 3: Cadena de ataque completa

El payload XSS ejecutaba un script que:

  1. Realizaba una petición fetch() al endpoint de cambio de email con las cookies del admin
  2. Cambiaba el email del administrador por uno controlado por el atacante
  3. Solicitaba un reset de password al nuevo email
  4. El atacante obtenía acceso completo a la cuenta de administrador
Flujo del ataque
1. Atacante registra cuenta con organización = [XSS payload]
2. Admin visita /admin/users → XSS se ejecuta en su contexto
3. Script cambia el email del admin via /api/account/update-email
4. Atacante solicita password reset al email controlado
5. Account takeover completo del administrador

Impacto

  • Account takeover de cualquier cuenta de administrador
  • Acceso al panel de administración con todos los datos de la plataforma
  • Modificación de datos de otros usuarios desde el panel admin
  • Posible escalada a otros sistemas internos accesibles desde el panel

Remediación

  1. Sanitizar todo input del usuario — Escapar o eliminar caracteres HTML en campos de perfil antes de renderizarlos. Usar Content Security Policy.
  2. Implementar tokens CSRF — Todos los endpoints que modifican estado deben validar un token anti-CSRF.
  3. Requerir confirmación para cambios criticos — El cambio de email debe requerir la password actual y confirmación por email.
  4. Cabeceras de seguridad — Implementar X-Content-Type-Options, X-Frame-Options y CSP estricta.