XSS cheatsheet - pruebas seguras y corrección paso a paso

6 de noviembre de 2026

Logos de Ironhackers y JavaScript. Documento de referencia sobre XSS.

Índice

Una prueba XSS puede parecer tan simple como introducir un texto en un formulario, pero el resultado depende de dónde termina ese dato y de cómo lo interpreta el navegador. Esta guía tipo xss cheatsheet reúne payloads de prueba no destructivos, técnicas para identificar el contexto, diferencias entre XSS reflejado, almacenado y DOM, y pasos para verificar y corregir el problema en un entorno autorizado.

Una referencia rápida para probar XSS con criterio

  • Contexto primero: el mismo payload no funciona igual dentro de HTML, atributos, JavaScript o una URL.
  • Payloads seguros: utiliza marcadores como alert(1) o console.log(1), nunca técnicas para robar cookies o modificar datos.
  • Tres variantes: distingue entre XSS reflejado, almacenado y basado en DOM.
  • Defensa correcta: aplica codificación de salida según el contexto y valida la solución con nuevas pruebas.
  • Autorización: trabaja únicamente sobre aplicaciones propias, laboratorios o programas con permiso explícito.

Qué debe aportar una buena guía de XSS

Una referencia útil no es una lista interminable de cadenas para copiar y pegar. Yo la utilizo como un mapa de decisión que ayuda a responder tres preguntas: dónde entra el dato, cómo lo procesa la aplicación y qué interpreta finalmente el navegador.

El Cross-Site Scripting permite que contenido controlado por un usuario se ejecute dentro del origen de una aplicación confiable. El impacto puede ir desde alterar la interfaz hasta realizar acciones con la sesión de la víctima, aunque la gravedad real depende de los permisos disponibles y de las defensas activas.

Las pruebas de este artículo están pensadas para demostrar ejecución sin acceder a información privada. Un resultado visual con alert(1) confirma una posibilidad técnica, pero no autoriza a extraer tokens, leer datos, enviar peticiones destructivas ni probar contra terceros.

Identifica el contexto antes de introducir un payload

El error que más veo al empezar es probar diez variantes sin mirar el HTML generado. Antes de elegir una cadena, inspecciono la respuesta en el navegador y compruebo si mi entrada aparece como texto, dentro de un atributo, en un bloque JavaScript o en el DOM creado por un script.

Contexto Qué observar Prueba inicial
Texto HTML La entrada aparece entre etiquetas, como en un mensaje o título. Marcador único y, si está permitido en el laboratorio, una etiqueta SVG no destructiva.
Atributo HTML El valor termina dentro de value, title, href u otro atributo. Comprobar si las comillas se codifican o permiten cerrar el atributo.
Cadena JavaScript El dato se inserta entre comillas dentro de un bloque o evento. Verificar si se puede salir de la cadena sin romper el script.
URL La entrada se convierte en destino de un enlace, formulario o redirección. Revisar el esquema permitido y si la aplicación valida el destino.
DOM El servidor no refleja el dato, pero JavaScript lo lee desde la URL, almacenamiento o mensajes. Seguir el flujo desde la fuente hasta el sink peligroso.

La codificación también cambia el diagnóstico. Si ves < en el código fuente, probablemente la aplicación está tratando tu entrada como texto HTML. Eso es positivo en ese contexto, pero no demuestra que todos los demás puntos de salida estén protegidos.

Diagrama de ataque XSS: atacante envía enlace malicioso, víctima hace clic, sitio carga script, datos robados.

Payloads de prueba seguros según el contexto

Los siguientes ejemplos sirven para un laboratorio local o una evaluación autorizada. Los muestro escapados para que puedan leerse sin ejecutarse en esta página. En una prueba real, sustituye el marcador por un valor único, por ejemplo xss-prueba-4821, para rastrear dónde aparece.

Texto HTML

Cuando la entrada aparece directamente entre etiquetas, empieza con un marcador de texto. Si necesitas confirmar interpretación HTML en un entorno controlado, una prueba habitual es . El elemento SVG resulta útil porque permite comprobar si se aceptan etiquetas y manejadores de evento sin depender de un bloque script.

Si la aplicación convierte los caracteres especiales en entidades HTML, el navegador mostrará la cadena como texto y la ejecución no debería producirse. En ese caso, no fuerces el resultado probando evasiones indiscriminadamente: revisa si existe otro punto de salida con un contexto distinto.

Atributos HTML

En un valor entre comillas, la pregunta es si la aplicación mantiene el dato dentro del atributo. Para un laboratorio, una prueba de cierre de atributo puede representarse como " autofocus onfocus="alert(1). El objetivo es comprobar el análisis del marcado, no crear un vector reutilizable contra usuarios reales.

Los atributos de URL requieren una revisión separada. Un enlace que acepte esquemas activos, como javascript:, puede ser peligroso, pero muchos navegadores y frameworks aplican restricciones adicionales. Por eso compruebo tanto el HTML final como el comportamiento al activar el enlace.

Cadenas JavaScript

Cuando el valor se inserta en una cadena JavaScript, el carácter decisivo suele ser la comilla utilizada por el código. Una prueba controlada para una cadena delimitada por comilla simple es ';alert(1);//. Para una cadena con comillas dobles, la variante debe adaptarse al delimitador.

Un fallo frecuente consiste en probar este ejemplo dentro de un atributo HTML y concluir que la aplicación es segura porque no ocurre nada. Cada contexto necesita su propia prueba y, sobre todo, su propia estrategia de codificación.

Lee también: Flipper Zero - ¿Qué es y para qué sirve realmente?

Fuentes y sinks del DOM

En el XSS basado en DOM, el servidor puede devolver una respuesta aparentemente limpia. El riesgo aparece cuando un script toma datos de location.hash, location.search, document.referrer o un mensaje y los envía a un sink como innerHTML o document.write.

Para comprobarlo, uso un marcador inofensivo en el fragmento de la URL y sigo su recorrido con las herramientas de desarrollador. Si el código termina en un sink que interpreta HTML, la corrección debe hacerse en el punto de inserción, no únicamente filtrando la entrada al principio.

Un proceso práctico para probar XSS en un laboratorio

Yo separo la evaluación en pasos pequeños. Así es más fácil explicar el hallazgo, reproducirlo y evitar que una prueba agresiva afecte a datos de usuarios.

  1. Define el alcance. Confirma el dominio, las cuentas permitidas, los horarios y las acciones excluidas.
  2. Localiza las entradas. Revisa formularios, parámetros GET y POST, cabeceras controlables, comentarios, perfiles y mensajes.
  3. Introduce un canario. Usa una cadena única para saber si el dato se refleja, se almacena o se transforma.
  4. Inspecciona el contexto. Comprueba el código fuente, el DOM final y los scripts que manipulan el valor.
  5. Prueba una confirmación mínima. Usa una señal local como alert(1) o console.log(1).
  6. Documenta el flujo. Anota entrada, transformación, salida, navegador, usuario afectado y resultado.
  7. Repite tras la corrección. Verifica el mismo caso y varios contextos relacionados.

Para XSS reflejado, la evidencia suele desaparecer al cerrar la respuesta o cambiar la petición. En el XSS almacenado, el dato queda guardado y puede ejecutarse cada vez que otro usuario visita la página. El caso DOM exige seguir la ejecución en el cliente, incluso cuando la respuesta HTTP no contiene el marcador.

Burp Suite y las herramientas de desarrollador del navegador ayudan a observar estas diferencias, pero ninguna herramienta sustituye el razonamiento sobre el contexto. Las automatizaciones encuentran candidatos; la confirmación fiable requiere entender qué parser procesa el dato.

Cómo separar un hallazgo real de un falso positivo

Encontrar una cadena en la respuesta no equivale a encontrar XSS. Primero compruebo si el navegador la interpreta como código o simplemente la muestra como texto. Una aplicación puede reflejar perfectamente un valor y, al mismo tiempo, codificarlo de forma segura.

También reviso si la ejecución ocurre con una cuenta sin privilegios y en una sesión limpia. Una política CSP puede bloquear una prueba concreta, pero eso no siempre significa que el contexto esté corregido. La política es una capa adicional, no un sustituto de la codificación contextual.

Señal observada Interpretación probable Qué hacer
El marcador aparece codificado La salida se trata como texto en ese punto. Revisar otros puntos de salida y el DOM.
La etiqueta aparece en el DOM, pero no ejecuta Puede existir sanitización, CSP o un contexto incorrecto. Inspeccionar consola, políticas y código cliente.
Se ejecuta solo tras guardar el dato Probable XSS almacenado. Evaluar qué usuarios visualizan ese contenido.
Solo funciona con una URL manipulada Probable XSS reflejado o DOM. Registrar la fuente exacta y la ruta de ejecución.

Una buena prueba de impacto no necesita robar una cookie. Basta con demostrar ejecución controlada, describir el contexto y explicar qué permisos tendría una víctima afectada. Esa forma de trabajar produce informes más sólidos y reduce el riesgo operativo.

Cómo corregir el problema sin depender de filtros

La medida principal es la codificación de salida específica para cada contexto. Codificar para HTML no sirve automáticamente para JavaScript, CSS o URLs. La aplicación debe usar las funciones de escape recomendadas por su framework justo antes de insertar el dato en la respuesta.

  • HTML: trata la entrada como texto y codifica caracteres especiales.
  • Atributos: usa comillas, codificación adecuada y evita construir atributos dinámicamente.
  • JavaScript: no concatena datos del usuario en código; utiliza estructuras de datos seguras.
  • DOM: prefiere textContent frente a innerHTML cuando solo necesitas texto.
  • HTML permitido: aplica una sanitización mantenida y configurada para ese caso concreto.
  • CSP: añade una política restrictiva como defensa en profundidad, sin presentarla como solución única.

Los filtros basados en palabras prohibidas suelen fallar porque no entienden el contexto completo ni las reglas de los parsers. OWASP recomienda centrar la defensa en la codificación contextual y en APIs seguras, una orientación mucho más estable que mantener una lista de cadenas peligrosas.

Después de corregir, pruebo entradas con comillas, etiquetas, entidades, caracteres Unicode y variaciones de codificación. También reviso las plantillas, los componentes reutilizados y las rutas de administración, porque un parche aplicado a un formulario no protege automáticamente el resto de la aplicación.

La disciplina que convierte una lista de payloads en una prueba útil

El valor de esta referencia no está en encontrar la cadena más llamativa, sino en entender cómo viaja el dato desde la entrada hasta el navegador. Un marcador único, una confirmación local y una documentación clara suelen aportar más que decenas de intentos de evasión.

Para aprender, prefiero practicar en laboratorios aislados y revisar los ejemplos de OWASP y PortSwigger junto con el código de la aplicación. En una evaluación profesional, mantengo el alcance por escrito, evito cualquier acceso a información real y comunico el hallazgo con pasos reproducibles y una corrección verificable.

La regla práctica es sencilla: identifica el contexto, prueba de forma mínima, demuestra el riesgo sin causar daño y corrige en el punto adecuado. Así, una guía de XSS deja de ser un inventario de payloads y se convierte en una herramienta real de hacking ético.

Este artículo tiene un carácter exclusivamente informativo y educativo. El material se ha elaborado con el apoyo de modernas herramientas analíticas y lingüísticas (IA). Antes de tomar una decisión, consulta a un experto.

Preguntas frecuentes

Primero comprueba si la entrada termina como texto HTML, atributo, cadena JavaScript, URL o dato procesado por el DOM. Después usa una prueba mínima adaptada, como un marcador único, alert(1) o console.log(1), sin acceder a información privada ni modificar datos.

El XSS reflejado suele desaparecer al cerrar la respuesta o cambiar la petición. El almacenado queda guardado y puede ejecutarse cuando otro usuario visita el contenido. En el XSS basado en DOM, el servidor puede devolver una respuesta limpia, pero JavaScript lleva datos de fuentes como location.hash o location.search a sinks como innerHTML o document.write.

Que el valor aparezca en la respuesta no demuestra ejecución. Revisa el código fuente, el DOM final, la consola y las políticas CSP para confirmar si el navegador interpreta la entrada como código o solo como texto codificado. También conviene repetir la prueba con una cuenta sin privilegios y una sesión limpia.

Aplica codificación de salida específica para cada contexto y evita concatenar datos del usuario en código JavaScript. En el DOM, prefiere textContent frente a innerHTML cuando solo necesites texto; si debes permitir HTML, usa una sanitización mantenida. Una CSP restrictiva aporta defensa en profundidad, pero no sustituye la corrección contextual.

Calificar artículo

Calificación: 0.00 Número de votos: 0

Etiquetas:

xss javascript dom csp sanitización

Compartir artículo

Joel Razo

Joel Razo

Nací como Joel Razo y tengo 14 años de experiencia en el fascinante mundo de la ciberseguridad, la privacidad y el hacking ético. Desde que descubrí la importancia de proteger la información personal y la integridad de los sistemas, me he dedicado a profundizar en estos temas, buscando siempre maneras de hacer que la tecnología sea más segura y accesible para todos. Me apasiona desmitificar conceptos complejos y ayudar a los lectores a comprender los riesgos y las mejores prácticas en un entorno digital en constante cambio. A lo largo de mi carrera, he trabajado en diversos aspectos de la ciberseguridad, desde la evaluación de vulnerabilidades hasta la implementación de soluciones de seguridad. Me gusta investigar y verificar fuentes, comparar información y seguir las tendencias más recientes para ofrecer contenido útil, preciso y fácil de entender. Mi compromiso es brindar a los lectores información actualizada que les permita navegar por el mundo digital con confianza y seguridad.

Escribe un comentario