FlawOpen

flawopen.com/XSS/Tipos de XSS

XSS reflejado, almacenado y basado en DOM: ¿en qué se diferencian?

Página de referencia
Respuesta breve

XSS reflejado, almacenado y basado en DOM describen rutas distintas desde datos no confiables hasta un contexto inseguro del navegador. Pueden solaparse: identifica dónde entra el valor, si persiste, qué código lo renderiza y a quién llega.

Los tres tipos

XSS reflejado — el valor está en la solicitud

Un valor de la solicitud se inserta en la respuesta sin codificación adecuada al contexto, y el navegador lo interpreta como marcado o script. Un atacante puede enviar un enlace preparado a la víctima, pero el fallo es la representación insegura de datos de la solicitud. Corrige el contexto de salida en el punto de renderizado.

XSS almacenado — el valor persiste

El contenido no confiable se guarda y luego se muestra de forma insegura a otros usuarios, por ejemplo en un comentario o perfil. Cada visitante que carga ese contenido puede recibir el mismo contexto inseguro hasta corregir el valor guardado o la ruta de renderizado.

XSS basado en DOM — el código cliente envía datos a un sink inseguro

JavaScript del cliente lee un origen no confiable (como location.hash, un parámetro de consulta o datos del servidor) y lo pasa a un sink DOM inseguro como innerHTML. El valor puede no llegar al servidor, pero no es un requisito: describe una ruta cliente de origen a sink y puede solaparse con la entrega reflejada o almacenada. Corrige el flujo del cliente.

Por qué importa la distinción al corregirlo

Corrige XSS en el punto de renderizado con codificación de salida adecuada al contexto o una API DOM segura. El XSS reflejado y almacenado suele incluir salida renderizada en el servidor, pero el renderizado del cliente también puede crear un sink inseguro. Para XSS basado en DOM, prefiere textContent a innerHTML para texto; si necesitas HTML enriquecido, usa un saneador mantenido con una política explícita. La codificación del servidor no sustituye la revisión de flujos origen-sink del cliente.

Estas categorías pueden solaparse

El XSS reflejado y el almacenado describen cómo llega la entrada a la página y si persiste. DOM-based describe un flujo de origen a sink en el cliente. No son categorías excluyentes: el texto persistido de un perfil que el código cliente inserta en innerHTML puede ser XSS almacenado y DOM-based a la vez.

XSS DOM: sink inseguro y representación solo como texto

INSEGURO — interpretar texto no confiable como HTML
const value = new URLSearchParams(location.search).get("q") ?? "";
target.innerHTML = value;
MÁS SEGURO PARA TEXTO — mostrarlo como texto
const value = new URLSearchParams(location.search).get("q") ?? "";
target.textContent = value;

Referencias

Véase también Cross-Site Scripting (XSS, CWE-79): cómo funciona y cómo evitarlo en cada lenguaje — flawopen.com Riesgos de seguridad de addJavascriptInterface en Android Protección XSS de Angular: valores seguros y APIs de omisión XSS por MIME sniffing: Content-Type y nosniff CSP y escape de salida: ¿necesitas ambos? ¿Es seguro dangerouslySetInnerHTML en React? ¿DOMPurify basta para proteger innerHTML?