system onlinepath: /guias/hacking/cross-site-scripting-como-funciona-un-ataque-xss/mode: knowledge_baselocal:
Hacking ético · Nivel intermedio

Cross-Site Scripting: cómo funciona un ataque XSS

El XSS logra que el navegador de la víctima ejecute código del atacante como si fuera del sitio de confianza. Es una de las vulnerabilidades web más extendidas, y su causa raíz es simple: mezclar datos con código.

13 min de lectura▣ Actualizada el ◇ Por Underc0de
Respuesta rápida

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
  1. 01Qué es y por qué es peligroso
  2. 02Los tres tipos de XSS
  3. 03La causa raíz
  4. 04Las defensas
  5. 05Errores frecuentes
  6. 06Preguntas frecuentes
  7. 07Fuentes

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

Los tres tipos de ataque Cross-Site Scripting y su causa raíz común, presentados como escenarios. Primer tipo, XSS reflejado: un atacante prepara un enlace o formulario que contiene código malicioso en sus parámetros y engaña a la víctima para que lo use; el sitio recibe ese parámetro y lo refleja de vuelta en la página de respuesta sin limpiarlo, de modo que el navegador de la víctima ejecuta el código; se destaca que requiere que la víctima haga clic en un enlace preparado, y que el código no queda guardado en el sitio sino que solo actúa en esa respuesta puntual. Segundo tipo, XSS almacenado, señalado como el más peligroso: el atacante envía el código malicioso a través de una entrada que el sitio guarda de forma permanente, como un comentario, una publicación o un campo de perfil; a partir de ahí, el código queda almacenado en el sitio y se ejecuta automáticamente en el navegador de todas las personas que visiten esa página, sin necesidad de engañarlas una por una, lo que amplifica enormemente su alcance. Tercer tipo, XSS basado en el DOM: ocurre enteramente dentro del navegador, sin que el servidor intervenga, y surge cuando el propio código JavaScript de la página toma datos de entrada, por ejemplo de la dirección o de la propia página, y los inserta de forma insegura en el documento, provocando la ejecución del código malicioso del lado del cliente. En el centro, resaltada como la causa raíz común a los tres tipos, la idea clave: el sitio mezcla datos con código, es decir toma algo que escribió un usuario y lo inserta en la página sin distinguir que es un dato para mostrar y no instrucciones para ejecutar, de modo que el navegador termina interpretando como código lo que debía ser simple texto. A la derecha, qué puede lograr un XSS exitoso: robar la sesión del usuario y suplantarlo, leer o modificar el contenido de la página incluidos datos privados, realizar acciones en nombre de la víctima, o redirigirla a un sitio de phishing, todo dentro del contexto del sitio de confianza y sin que la persona lo note. Abajo, resaltadas, las defensas: la principal es la codificación de salida, que consiste en tratar todo dato que se muestra como texto y nunca como código, escapando los caracteres especiales para que el navegador no los interprete como instrucciones, algo que los marcos de desarrollo modernos hacen automáticamente; como defensa en profundidad se suma la política de seguridad de contenido o CSP, que restringe qué scripts puede ejecutar la página y limita el daño aunque una inyección logre colarse; y se complementa con la validación de las entradas. Al pie, el encuadre: la guía es defensiva y educativa, orientada a entender el ataque para prevenirlo en sistemas propios o autorizados, nunca a atacar sitios ajenos.
Reflejado (viaja en un enlace), almacenado (queda guardado y afecta a todos; el más peligroso) y basado en el DOM (ocurre en el navegador). La causa raíz común: mezclar datos con código.

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:

i
Mezclar datos con código

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

  1. Underc0de, foro. Sección Hacking. Vulnerabilidades web y su explotación en laboratorios.
  2. Underc0de, foro. Sección Desarrollo web. Desarrollo seguro y prevención de XSS.

Documentación oficial

  1. OWASP. Cross Site Scripting (XSS). Descripción de referencia, citada en la guía.
  2. OWASP. XSS Prevention Cheat Sheet. Cómo prevenirlo.
  3. Mozilla. Content Security Policy (CSP). La defensa en profundidad.
  4. OWASP. OWASP Top 10. El XSS dentro de la familia de inyecciones.