El Cross-Site Scripting (XSS) es una vulnerabilidad web que permite a un atacante inyectar código (JavaScript) que se ejecuta en el navegador de otra persona, dentro del contexto de un sitio de confianza. Como el código corre «desde» ese sitio, puede hacer lo que el usuario podría: robar su sesión (y así suplantarlo), leer datos de la página, modificar lo que ve, o redirigirlo a un sitio malicioso. Hay tres tipos. El reflejado: el código viaja en un enlace o formulario y el sitio lo «refleja» de vuelta sin limpiarlo; requiere que la víctima haga clic en un enlace preparado. El almacenado: el código malicioso queda guardado en el sitio (un comentario, un perfil) y se ejecuta en todos los que lo ven; es el más peligroso. Y el basado en el DOM: ocurre enteramente en el navegador, por cómo el JavaScript de la página maneja datos de entrada. La causa raíz es siempre la misma: el sitio mezcla datos con código —toma algo que escribió un usuario y lo inserta en la página sin distinguir que es dato, no instrucciones—. La defensa central es codificar la salida: al mostrar datos, tratarlos como texto, nunca como código (los marcos modernos lo hacen solo). Se refuerza con una Content Security Policy (CSP) y validando la entrada. Guía defensiva y educativa: entender el ataque para prevenirlo, en entornos legales.
Ver índice de contenidos
Qué es y por qué es peligroso
El Cross-Site Scripting aprovecha que las páginas web mezclan contenido y código: si un atacante logra que su JavaScript se cuele en una página y el navegador de otra persona lo ejecute, ese código corre con los permisos del sitio de confianza, como si el propio sitio lo hubiera puesto.
El navegador confía, y ahí está el daño
El navegador no distingue si el JavaScript de una página lo puso el sitio legítimo o un atacante: lo ejecuta igual, con acceso a todo lo de esa página. Por eso un XSS exitoso puede robar la sesión del usuario (las credenciales que lo mantienen logueado) y suplantarlo, leer o modificar lo que hay en la página (incluidos datos privados), realizar acciones en su nombre, o redirigirlo a un sitio de phishing. Todo sin que la víctima note nada raro, porque ocurre dentro del sitio en el que confía.
El XSS es una de las vulnerabilidades web más extendidas y forma parte de la familia de inyecciones del OWASP Top 10. Esta guía profundiza en él; la visión general de SQLi, XSS y CSRF las presenta juntas.
Los tres tipos de XSS
El XSS se clasifica en tres tipos según dónde y cómo se inyecta el código:
- Reflejado. El código viaja en un enlace o formulario (en un parámetro), y el sitio lo «refleja» de vuelta en su respuesta sin limpiarlo. Requiere engañar a la víctima para que use ese enlace preparado; no queda guardado, actúa solo en esa respuesta.
- Almacenado (el más peligroso). El código malicioso se envía a través de una entrada que el sitio guarda de forma permanente —un comentario, una publicación, un perfil— y luego se ejecuta en el navegador de todos los que ven esa página, sin necesidad de engañar a nadie uno por uno. Su alcance es enorme.
- Basado en el DOM. Ocurre enteramente en el navegador, sin que el servidor intervenga: surge cuando el propio JavaScript de la página toma datos de entrada (de la URL, por ejemplo) y los inserta de forma insegura en el documento.
La causa raíz
Los tres tipos comparten una misma causa, y entenderla es lo que permite prevenir todos a la vez:
El XSS ocurre porque el sitio toma algo que escribió un usuario y lo inserta en la página sin distinguir que es un dato, no código. El navegador, al encontrar lo que parece un script en el HTML, lo ejecuta —no tiene forma de saber que en realidad era «texto que un usuario escribió»—. Es exactamente la misma causa raíz que la inyección SQL: confundir datos con instrucciones. Toda la familia de inyecciones nace de ahí. Por eso la defensa no es «filtrar palabras malas» (siempre se escapa alguna), sino tratar los datos como datos de forma sistemática.
Esta comprensión es la clave: no se trata de perseguir cada truco de ataque conocido, sino de arreglar la raíz —que los datos no se interpreten nunca como código—. Una vez que se hace eso bien, los tres tipos de XSS quedan cerrados.
Las defensas
La prevención del XSS se apoya en una defensa central y varias capas de refuerzo:
- Codificación de salida (la defensa principal). Al mostrar un dato en la página, hay que escaparlo: convertir los caracteres especiales del HTML (como
<y>) en su forma inofensiva, de modo que el navegador los muestre como texto y no los interprete como código. Así, si un usuario escribió algo que parece un script, se muestra literalmente en vez de ejecutarse. Los marcos de desarrollo modernos (como React y otros) hacen esta codificación automáticamente, y por eso previenen la mayoría de los XSS por defecto. - Content Security Policy (CSP). Una cabecera que le dice al navegador qué scripts puede ejecutar la página. Aunque una inyección se cuele, la CSP puede impedir que el script malicioso corra. Es defensa en profundidad: no reemplaza a codificar la salida, la refuerza.
- Validación de entrada. Rechazar en el origen datos que no tienen sentido para el campo (aunque no es suficiente por sí sola; la codificación de salida es lo que cierra el problema).
- Cookies de sesión protegidas (marcadas para que el JavaScript no pueda leerlas), de modo que un XSS no pueda robar la sesión tan fácilmente.
La regla que ordena todo: la defensa correcta contra el XSS es arreglar la causa raíz (tratar los datos como datos), y los marcos modernos ayudan mucho. Todo esto se prueba y aplica en sistemas propios o con autorización: usar XSS contra sitios ajenos es ilegal.
Errores frecuentes
- Confiar solo en filtrar «palabras malas». Las listas negras siempre dejan pasar algo; hay que codificar la salida.
- Insertar HTML crudo con datos de usuario. Es la vía directa al XSS; usar las funciones seguras del marco.
- Creer que el marco protege siempre. Ciertas operaciones (insertar HTML sin sanitizar) lo saltan; hay que conocerlas.
- No usar CSP. Se pierde una capa de defensa en profundidad valiosa.
- Cookies de sesión accesibles por JavaScript. Facilita el robo de sesión ante un XSS.
- Validar entrada pero no codificar salida. El problema se cierra al mostrar, no solo al recibir.
- Probar contra sitios ajenos. Solo en entornos propios o autorizados; lo contrario es ilegal.
Preguntas frecuentes
¿Qué es un ataque XSS y por qué es peligroso?
El Cross-Site Scripting, o XSS, es una vulnerabilidad web que permite a un atacante inyectar código, típicamente JavaScript, que se ejecuta en el navegador de otra persona dentro del contexto de un sitio de confianza. Su peligro reside en que el navegador no distingue si el código de una página lo colocó el sitio legítimo o un atacante: lo ejecuta igual, con acceso a todo lo que hay en esa página y con los permisos del sitio. Por eso un XSS exitoso puede robar la sesión del usuario, es decir las credenciales que lo mantienen conectado, y con ellas suplantarlo; puede leer o modificar el contenido de la página, incluidos datos privados; puede realizar acciones en nombre de la víctima; o puede redirigirla a un sitio de phishing. Todo esto ocurre sin que la persona note nada extraño, precisamente porque sucede dentro del sitio en el que confía. Es una de las vulnerabilidades web más extendidas y pertenece a la familia de las inyecciones, que figura entre los riesgos principales del OWASP Top 10. Comprender cómo funciona es el primer paso para prevenirlo eficazmente.
¿Cuáles son los tres tipos de XSS?
Se clasifican según dónde y cómo se inyecta el código. El XSS reflejado viaja en un enlace o formulario, dentro de un parámetro, y el sitio lo refleja de vuelta en su página de respuesta sin limpiarlo, de modo que se ejecuta en el navegador de la víctima; requiere engañar a la persona para que use un enlace preparado, y el código no queda guardado sino que solo actúa en esa respuesta puntual. El XSS almacenado, considerado el más peligroso, se produce cuando el código malicioso se envía a través de una entrada que el sitio guarda de forma permanente, como un comentario, una publicación o un campo de perfil, y a partir de ahí se ejecuta automáticamente en el navegador de todas las personas que visiten esa página, sin necesidad de engañarlas individualmente, lo que amplifica enormemente su alcance. El XSS basado en el DOM ocurre enteramente dentro del navegador, sin intervención del servidor, y surge cuando el propio código JavaScript de la página toma datos de entrada, por ejemplo de la dirección, y los inserta de forma insegura en el documento. A pesar de sus diferencias, los tres comparten la misma causa raíz y, por lo tanto, la misma familia de defensas.
¿Cuál es la causa raíz del XSS?
La causa raíz, común a los tres tipos, es que el sitio mezcla datos con código: toma algo que escribió un usuario y lo inserta en la página sin distinguir que se trata de un dato para mostrar y no de instrucciones para ejecutar. Cuando el navegador encuentra en el HTML de la página algo que parece un script, lo ejecuta, porque no tiene forma de saber que en realidad era simplemente texto que un usuario había escrito. Esta confusión entre datos e instrucciones es exactamente la misma que origina la inyección de SQL y, en general, toda la familia de ataques de inyección. Comprender esto es fundamental porque cambia por completo el enfoque de la defensa: en lugar de intentar perseguir y bloquear cada truco de ataque conocido, tarea imposible porque siempre aparecen variantes nuevas, la solución consiste en arreglar la raíz, garantizando que los datos nunca se interpreten como código. Una vez que un sitio trata sistemáticamente los datos como datos y no como instrucciones, los tres tipos de XSS quedan cerrados de una sola vez, sin necesidad de conocer cada variante específica del ataque.
¿Cómo se previene el XSS?
La defensa principal es la codificación de salida, que consiste en escapar los datos en el momento de mostrarlos en la página: convertir los caracteres especiales del HTML en su forma inofensiva, de manera que el navegador los muestre como texto y no los interprete como código. Así, si un usuario escribió algo que parece un script, se mostrará literalmente en la página en lugar de ejecutarse. La buena noticia es que los marcos de desarrollo web modernos realizan esta codificación de forma automática, y por eso previenen la mayoría de los ataques XSS por defecto, siempre que no se usen deliberadamente funciones que insertan HTML sin sanitizar. A esta defensa central se le suman varias capas de refuerzo. La política de seguridad de contenido, conocida como CSP, es una cabecera que indica al navegador qué scripts puede ejecutar la página, de modo que aunque una inyección se cuele, pueda impedirse que el código malicioso corra; es una defensa en profundidad que complementa, no reemplaza, a la codificación de salida. También ayudan la validación de las entradas y proteger las cookies de sesión para que el JavaScript no pueda leerlas, dificultando el robo de sesión. La clave es atacar la causa raíz tratando los datos como datos.
¿Los marcos modernos como React eliminan el XSS?
Los marcos de desarrollo web modernos reducen enormemente el riesgo de XSS porque, por diseño, codifican automáticamente los datos al insertarlos en la página, tratándolos como texto en lugar de como código. Esto significa que, en el uso normal, previenen la gran mayoría de los ataques XSS sin que quien desarrolla tenga que hacer nada especial, lo cual es una mejora de seguridad muy importante respecto de escribir HTML manualmente. Sin embargo, no eliminan el riesgo por completo, y es fundamental entenderlo para no caer en una falsa sensación de seguridad. Estos marcos ofrecen ciertas funciones o mecanismos que permiten insertar HTML crudo sin sanitizar, pensados para casos legítimos concretos, y si se usan con datos que provienen de usuarios sin las precauciones adecuadas, se vuelve a abrir la puerta al XSS. Del mismo modo, el XSS basado en el DOM puede surgir por cómo el propio código de la aplicación manipula datos, incluso dentro de un marco. Por lo tanto, la respuesta es que los marcos modernos son una defensa muy poderosa y hacen que lo seguro sea lo predeterminado, pero quien desarrolla debe conocer cuáles son las operaciones que saltan esa protección y usarlas con extremo cuidado, complementando siempre con defensas en profundidad como la CSP.
¿En qué se diferencia esta guía de la de SQLi, XSS y CSRF?
La guía sobre SQLi, XSS y CSRF ofrece una visión general de las tres vulnerabilidades web más emblemáticas presentándolas juntas, explicando qué es cada una, en qué se parecen y en qué se distinguen, de modo que sirve como panorama introductorio de estas amenazas relacionadas. Esta guía, en cambio, se concentra en profundidad exclusivamente en el Cross-Site Scripting, permitiéndose desarrollar con más detalle cómo funciona, los tres tipos específicos que existen, la causa raíz que comparten y, sobre todo, el conjunto completo de defensas para prevenirlo, desde la codificación de salida hasta la política de seguridad de contenido. La recomendación es usar la guía general para obtener una comprensión inicial y comparativa de las tres vulnerabilidades, y esta guía cuando se necesita entender el XSS a fondo, ya sea para prevenirlo al desarrollar o para comprenderlo en el contexto de una auditoría autorizada. Del mismo modo existe una guía dedicada específicamente a la inyección de SQL, que profundiza en la otra gran inyección con la misma lógica. Todas comparten el enfoque defensivo y educativo, orientado a proteger sistemas propios o autorizados y siempre dentro de un marco legal.
Fuentes
Documentación oficial y material de la comunidad consultados para esta guía. Fecha de consulta: 28 de julio de 2026.
Aportes de la comunidad Underc0de
- Underc0de, foro. Sección Hacking. Vulnerabilidades web y su explotación en laboratorios.
- Underc0de, foro. Sección Desarrollo web. Desarrollo seguro y prevención de XSS.
Documentación oficial
- OWASP. Cross Site Scripting (XSS). Descripción de referencia, citada en la guía.
- OWASP. XSS Prevention Cheat Sheet. Cómo prevenirlo.
- Mozilla. Content Security Policy (CSP). La defensa en profundidad.
- OWASP. OWASP Top 10. El XSS dentro de la familia de inyecciones.