Reflected XSS (Non-Persistent)

📘 Tema

Este apartado explica el funcionamiento del XSS reflejado, un tipo de XSS no persistente, cómo detectarlo y cómo se explota realmente contra víctimas.


🧠 XSS No Persistente (Non-Persistent)

Existen dos tipos de XSS no persistente:

Tipo Dónde se procesa
🔁 Reflected XSS Servidor back-end
🧬 DOM-based XSS Navegador (lado cliente)
📌 Diferencia clave con Stored XSS

  • No se guarda en la base de datos

  • No persiste al recargar

  • Afecta solo al usuario objetivo


🔁 ¿Qué es Reflected XSS?

⚠️ Reflected XSS

Ocurre cuando:

  • La entrada del usuario llega al servidor

  • El servidor la devuelve en la respuesta

  • No se filtra ni se escapa correctamente

  • El navegador ejecuta el JavaScript

📌 Suele aparecer en:


🧪 Entorno vulnerable de práctica

🧩 Escenario

Aplicación tipo To-Do List, similar al ejemplo anterior, pero con validación fallida.

Accedemos a:

http://<IP>:<PUERTO>/

🖥️ Interfaz:

Ejemplo de entrada normal:

test
📌 Mensaje devuelto por el servidor:
{0BF15E61-69D4-4430-95BA-72FEC57151CB}.png

Task 'test' could not be added.

➡️ Nuestra entrada se refleja directamente en el mensaje.


🧨 Prueba de XSS reflejado

Probamos la misma carga básica:

<script>alert(window.origin)</script>

La enviamos pulsando Add.

📸 Resultado:
{F8FC45F8-2C07-4308-9EA5-38EAE0DA42E9}.png

✅ Confirmación

El código JavaScript se ejecutó → XSS reflejado confirmado


🔎 Análisis del comportamiento

Después del payload, el mensaje ahora muestra:
{FEE2AFFA-25C2-40A6-A5EF-E4E177B9A9E6}.png

Task '' could not be added.

📌 ¿Por qué aparecen comillas vacías?

🧠 Explicación

  • El navegador no renderiza <script> como texto

  • Ejecuta el código

  • El HTML visible queda vacío


📄 Confirmación en el código fuente

Al ver el código fuente (CTRL + U):
{6AFB5CE8-70BC-4A6B-9794-7EC69A323F2C}.png

<div style="padding-left:25px">
  Task '<script>alert(window.origin)</script>' could not be added.
</div>
💥 Clave técnica

La carga está:

  • Procesada por el servidor

  • Devuelta sin sanitizar

  • Ejecutada por el navegador


🔄 ¿Por qué NO es persistente?

🔁 Comportamiento

  • Si recargamos la página

  • O entramos de nuevo sin el payload

👉 El mensaje desaparece
👉 El script no se ejecuta

Esto confirma que es:

🎯 XSS Reflejado (Non-Persistent)

🎯 Entonces… ¿cómo se ataca a una víctima?

❓ Pregunta clave

Si no es persistente, ¿cómo afecta a otros usuarios?

La respuesta está en el tipo de petición HTTP.


🌐 Análisis de la petición HTTP

Abrimos las DevTools del navegador:

CTRL + Shift + INetwork

Repetimos la prueba y observamos:

📌 La petición es:

GET
{308AE074-0FF9-42C3-A757-5EDAC70029C8}.png

⚠️ Importante

Las peticiones GET envían los datos en la URL


🔗 Explotación real (enlace malicioso)

Si el payload viaja en la URL, el ataque consiste en:

🚨 Enviar un enlace malicioso a la víctima

Ejemplo conceptual:

http://<IP>:<PUERTO>/?task=<script>alert(window.origin)</script>

📌 Cuando la víctima:

👉 El navegador ejecuta el payload


🎣 Vectores comunes de ataque

📌 Reflected XSS suele explotarse vía:

  • Phishing

  • Emails

  • Chats

  • Redes sociales

  • Enlaces acortados

  • QR maliciosos


🧠 Comparación rápida: Stored vs Reflected

Característica Stored XSS Reflected XSS
Persistencia ✅ Sí ❌ No
Afecta a múltiples usuarios
Requiere interacción ✅ (clic)
Vector típico Formulario URL
Impacto Muy alto Medio

🧠 Resumen final

📌 Claves del Reflected XSS

  • No se almacena en la base de datos

  • Se ejecuta solo al visitar una URL maliciosa

  • Depende del servidor backend

  • Muy común en mensajes de error

  • Usado principalmente en ataques de phishing