DOM-based XSS

🧠 ¿Qué es DOM-based XSS?

⚠️ DOM XSS

Ocurre cuando:

  • La entrada del usuario NO llega al servidor

  • El JavaScript del navegador procesa la entrada

  • El DOM se modifica dinámicamente

  • El código malicioso se ejecuta en el cliente

📌 Diferencia clave:

Tipo XSS Procesamiento
Stored Servidor + BD
Reflected Servidor
DOM-based 🧠 Navegador (JavaScript)

🧪 Entorno vulnerable de práctica

🧩 Escenario

Aplicación web tipo To-Do List, visualmente igual a las anteriores.

Accedemos a:

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

Probamos a añadir un texto normal:

test

🖥️ Resultado:
Pasted image 20251215190346.png


🌐 Análisis clave: pestaña Network

Abrimos las DevTools:

CTRL + Shift + I → Network

Repetimos la acción (Add) y observamos:

Resultado importante

❌ NO se genera ninguna petición HTTP
Pasted image 20251215190410.png

📌 Esto indica que:


🔗 Parámetro en la URL (#)

Observamos que la URL cambia así:

http://<IP>:<PUERTO>/#task=test

🧠 ¿Por qué es importante #?

  • Todo lo que va después de #:

    • ❌ No se envía al servidor

    • ✅ Solo lo lee el navegador

  • Muy común en:

    • SPA

    • Aplicaciones JS modernas


📄 ¿Por qué no aparece en el código fuente?

Si miramos el código fuente con:

CTRL + U

📌 No veremos nuestro input.
Pasted image 20251215190431.png

🧠 Explicación

  • El HTML base se carga primero

  • Luego JavaScript modifica el DOM

Por eso:

  • No persiste

  • No aparece en el source original

Para verlo correctamente:

CTRL + SHIFT + C

➡️ HTML renderizado dinámicamente


🧩 Concepto clave: Source & Sink

📘 DOM XSS se basa en Source y Sink

Si controlas la Source y llega a un Sink inseguro, hay XSS.


🔹 Source (origen de la entrada)

🧠 Source

Es de dónde sale el dato que controla el usuario.

📌 Ejemplos comunes de Source:

📎 En este caso, la Source es el parámetro task:

var pos = document.URL.indexOf("task=");
var task = document.URL.substring(pos + 5, document.URL.length);

El atacante controla completamente el valor de task.


🔻 Sink (destino peligroso)

⚠️ Sink

Es la función que escribe la entrada del usuario en el DOM.

📌 Si el Sink no sanitiza, ejecutará código malicioso.

Funciones JavaScript peligrosas

Funciones jQuery peligrosas

📎 En este caso:

document.getElementById("todo").innerHTML =
"<b>Next Task:</b> " + decodeURIComponent(task);
🚨

Source controlable + Sink sin sanitización = DOM XSS


🧨 Ataque DOM XSS

❌ Payload clásico que NO funciona

<script>alert(window.origin)</script>
⚠️ ¿Por qué falla?

  • innerHTML bloquea <script>

  • Es una medida de seguridad del navegador


✅ Payload funcional (sin <script>)

<img src="" onerror=alert(window.origin)>
<img src="" onerror=alert(documento.cookie)>

{F7F0B176-CA46-4AD5-A6D8-8A6F04CB8675}.png

🧠 ¿Por qué funciona?

  • Se crea una imagen

  • src="" falla

  • Se dispara onerror

  • Ejecuta JavaScript


🔗 URL maliciosa final

El payload se pasa directamente en la URL:

http://<IP>:<PUERTO>/#task=<img src="" onerror=alert(window.origin)>

📸 Resultado:


🎯 Explotación real

🚨 DOM XSS se explota igual que Reflected XSS

📌 Envío de enlaces maliciosos vía:

👉 Cuando la víctima visita la URL:


🧠 Comparación rápida de los 3 XSS

Tipo Persistente Servidor Cliente
Stored XSS
Reflected XSS
DOM-based XSS

🧠 Resumen final

📌 Claves del DOM XSS

  • No llega al servidor

  • Totalmente del lado cliente

  • Basado en Source & Sink

  • Muy común en apps JS modernas

  • Difícil de detectar desde backend

  • Ideal para phishing y ataques dirigidos

On this page
  • 🧠 ¿Qué es DOM-based XSS?
  • 🧪 Entorno vulnerable de práctica
  • 🌐 Análisis clave: pestaña Network
  • 🔗 Parámetro en la URL (#)
  • 📄 ¿Por qué no aparece en el código fuente?
  • 🧩 Concepto clave: Source & Sink
    1. 🔹 Source (origen de la entrada)
    2. 🔻 Sink (destino peligroso)
      1. Funciones JavaScript peligrosas
      2. Funciones jQuery peligrosas
  • 🧨 Ataque DOM XSS
  • ❌ Payload clásico que NO funciona
  • ✅ Payload funcional (sin