Inicio/Tecnologías/Qué es XSS: Tipos de ataques, riesgos y cómo proteger tu sitio web
Tecnologías

Qué es XSS: Tipos de ataques, riesgos y cómo proteger tu sitio web

XSS (Cross Site Scripting) es una vulnerabilidad crítica en aplicaciones web que permite la ejecución de código malicioso en el navegador del usuario. Conoce los tipos de XSS, sus riesgos para usuarios y propietarios de sitios, y las mejores estrategias para protegerte eficazmente.

15 sept 2026
15 min
Qué es XSS: Tipos de ataques, riesgos y cómo proteger tu sitio web

XSS (Cross Site Scripting) es una vulnerabilidad de las aplicaciones web que permite a un atacante ejecutar su propio código JavaScript en el navegador de otro usuario. El servidor del sitio puede seguir funcionando normalmente: el problema surge porque la aplicación procesa incorrectamente los datos y permite que el navegador los interprete como parte de la página o como código ejecutable.

A través de XSS se puede modificar el contenido del sitio, mostrar formularios falsos, realizar acciones en nombre del usuario y acceder a parte de la información disponible en la página. El peligro se agrava porque el código malicioso se ejecuta dentro del propio sitio, teniendo los mismos privilegios en el navegador que el JavaScript legítimo de la página.

¿Qué es un ataque XSS y por qué se llama cross-site scripting?

Cross Site Scripting, o scripting entre sitios, ocurre cuando un sitio inserta datos no confiables de un usuario en una página HTML sin el escape adecuado o sin un procesamiento seguro. Como resultado, una cadena que debería mostrarse como texto puede ser interpretada por el navegador como parte del marcado o como código JavaScript.

Un ejemplo sencillo es un sitio con comentarios: el usuario introduce un mensaje, el servidor lo guarda y luego lo muestra a otros visitantes. Si la aplicación inserta estos datos directamente en el HTML sin verificarlos, un atacante podría intentar colocar una construcción que haga que el navegador ejecute JavaScript en vez de mostrar texto común.

En términos sencillos, XSS es como mezclar datos y comandos. El usuario solo debería poder enviar información al sitio (nombre, comentario, búsqueda u otro texto), pero por un error del desarrollador, el navegador puede interpretar parte de esos datos como instrucciones que debe ejecutar.

El nombre Cross Site Scripting es histórico y puede resultar confuso. El ataque no siempre requiere transferir scripts literalmente de un sitio a otro. El signo distintivo de una XSS es la ejecución de código no confiable en el contexto de una página en la que el usuario confía.

¿En qué se diferencia XSS de un hackeo tradicional?

En un hackeo clásico, el atacante intenta acceder al servidor, la base de datos, el panel administrativo o al sistema de archivos. XSS es diferente: el objetivo principal es el navegador del visitante.

No es necesario que el atacante tenga control total sobre el servidor. Basta con encontrar un lugar donde el sitio inserte datos externos de forma insegura en la página. Cuando la víctima abre esa página, el código malicioso se ejecuta en su dispositivo desde el navegador.

Por eso, XSS es distinto, por ejemplo, de una inyección SQL. En la inyección SQL los datos mal procesados pueden llegar a la base de datos, mientras que en XSS se convierten en código ejecutable en el navegador. Si quieres saber más sobre vulnerabilidades del lado del servidor, puedes consultar el artículo sobre qué es una inyección SQL, cómo funciona y cómo proteger tu sitio. Ambos ataques están relacionados con el manejo inseguro de datos no confiables, pero afectan diferentes partes de la aplicación web.

¿Cómo funciona un ataque XSS y cómo llega JavaScript a la página?

Un ataque XSS comienza cuando la aplicación web recibe datos de una fuente no confiable: un comentario, una búsqueda, un parámetro de URL, un nombre de usuario u otra información que el visitante puede modificar. Si el sitio inserta estos datos en la página sin un tratamiento seguro, el navegador podría interpretarlos como parte del HTML o JavaScript en vez de texto.

El error clave ocurre al generar la página: el servidor o el JavaScript del lado del cliente toma el valor recibido y lo coloca donde el navegador espera marcado o código. Así, unos datos especialmente preparados pueden cambiar la estructura del documento y hacer que el navegador ejecute una instrucción no prevista.

El navegador no distingue entre el código escrito por el desarrollador y el inyectado por el atacante. Si el JavaScript aparece en la página y no está bloqueado por mecanismos de seguridad, se ejecuta en el contexto del sitio actual.

Del input del usuario a la ejecución del script

La cadena típica inicia con un formulario o un parámetro de consulta: el usuario envía datos, la aplicación los recibe y luego los incorpora en la página HTML. Si el tratamiento es correcto, los caracteres especiales se transforman para que el navegador los muestre como texto.

Si no se escapan, el contenido puede cambiar la estructura del HTML. El navegador entonces analiza la página considerando los elementos y manejadores de eventos inyectados. Por eso, el problema no es solo la presencia de entrada de usuario, sino en qué contexto y cómo se muestra.

Esto puede ocurrir incluso sin guardar datos en el servidor: basta con que la aplicación tome un valor de la barra de direcciones o de otra fuente en el navegador y lo agregue de forma insegura al DOM. Por eso, XSS aparece tanto en sitios tradicionales con renderizado en servidor, como en aplicaciones web modernas donde gran parte de la interfaz es generada por JavaScript.

¿Qué puede hacer un JavaScript malicioso?

Las posibilidades de XSS dependen del sitio y la configuración del navegador. Un script malicioso puede leer el contenido disponible en la página, modificar la interfaz, rastrear acciones del usuario y enviar solicitudes en nombre de la pestaña abierta.

Por ejemplo, un atacante puede reemplazar parte de la interfaz con un formulario de inicio de sesión falso u otro elemento visualmente similar al real. Como la sustitución ocurre dentro del propio sitio, el usuario puede no notar que está interactuando con un elemento falso.

Además, el JavaScript puede actuar con los mismos permisos que tiene la página. Si el usuario ya está autenticado, el navegador puede adjuntar automáticamente sus datos de sesión en las solicitudes al mismo sitio. Por eso, XSS se puede usar no solo para leer información, sino también para realizar ciertas operaciones en nombre de la víctima.

XSS y robo de sesiones

Uno de los escenarios más conocidos está relacionado con las cookies de sesión. Después de iniciar sesión, el sitio suele dar al navegador un identificador de sesión para que el usuario no tenga que escribir la contraseña en cada solicitud.

Si esa cookie es accesible mediante JavaScript, un ataque XSS exitoso puede capturarla y enviarla al atacante. El identificador capturado puede usarse para intentar hacerse pasar por el usuario autenticado sin conocer la contraseña.

Los sitios modernos reducen este riesgo usando el atributo HttpOnly, que impide que JavaScript lea directamente las cookies protegidas. Sin embargo, esto no elimina el problema de XSS: el código malicioso aún puede interactuar con la página e iniciar acciones permitidas a través del navegador, por lo que la protección de la sesión debe complementar la eliminación de la vulnerabilidad, no reemplazarla.

Tipos de ataques XSS: Stored, Reflected y DOM XSS

Los principales tipos de ataques XSS se diferencian en el origen del código malicioso y en qué momento se ejecuta. Los más comunes son Stored XSS, Reflected XSS y DOM XSS. Para el usuario, el resultado suele ser el mismo: se ejecuta JavaScript ajeno en el navegador, pero la causa de la vulnerabilidad y la vía de entrega del código son distintas.

Stored XSS

Stored XSS, o XSS almacenado, ocurre cuando los datos maliciosos se guardan en el sitio y luego se muestran automáticamente a otros usuarios. El origen puede ser un comentario, un mensaje, la descripción de un perfil, una entrada en un foro o cualquier campo cuyo contenido se almacene en la base de datos.

El peligro de este escenario es que el atacante no necesita enviar un enlace especial a cada víctima. Basta con añadir el fragmento malicioso una vez en la sección vulnerable, y este puede cargarse a todos los visitantes que abran la página correspondiente.

Por eso, el Stored XSS se considera una de las variantes más graves de scripting entre sitios. Si la página vulnerable es popular, un solo script guardado puede afectar a una gran cantidad de usuarios.

Reflected XSS

Reflected XSS, o XSS reflejado, funciona de forma diferente. Los datos maliciosos no se almacenan en la base de datos, sino que se envían en la solicitud y se devuelven inmediatamente en la página generada.

Por ejemplo, un sitio puede mostrar la búsqueda del usuario en el encabezado de los resultados o mostrar un parámetro de la URL en un mensaje de error. Si el valor se inserta sin el escape adecuado, una solicitud preparada puede hacer que se ejecute JavaScript.

Este tipo de ataque suele requerir que el usuario abra un enlace preparado o envíe una solicitud específica. Por eso, el Reflected XSS suele combinarse con ingeniería social, mensajes de phishing o enlaces disfrazados.

DOM XSS

DOM XSS ocurre directamente en el navegador y está relacionado con la forma en que el JavaScript del lado del cliente procesa los datos. El servidor puede devolver una página completamente segura, pero la vulnerabilidad aparece después de cargarla en el navegador.

Por ejemplo, el script del sitio puede tomar un valor de la URL, del fragmento tras el símbolo #, de un parámetro de consulta u otra fuente, e insertarlo en la página de forma insegura. Si se usa una operación que permite interpretar la cadena como HTML, el atacante puede cambiar el DOM y lograr la ejecución de código.

La diferencia principal de DOM XSS es que el problema está en la lógica del cliente. La cadena maliciosa puede no enviarse nunca al servidor, por lo que detectarla solo con registros del servidor es más difícil.

Stored XSS está asociado a los datos almacenados, Reflected XSS a la inserción inmediata del input en la respuesta del servidor, y DOM XSS a la manipulación insegura de datos en el navegador. A pesar de las diferencias, la causa es la misma: la aplicación permite que datos no confiables lleguen a un contexto donde el navegador puede interpretarlos como código.

¿Por qué es peligrosa una XSS para usuarios y propietarios de sitios?

El peligro de XSS es que el código malicioso se ejecuta dentro del sitio legítimo en el que el usuario confía. Visualmente, la página puede parecer completamente normal, pero el navegador ya está realizando acciones no previstas por los desarrolladores.

Las consecuencias dependen de las capacidades de la aplicación. En un sitio, el XSS solo permite modificar la interfaz, pero en otro puede permitir ejecutar solicitudes como usuario autenticado o acceder a datos sensibles.

Robo de datos y acciones en nombre del usuario

El JavaScript malicioso puede leer información presente en la página, rastrear la interacción con la interfaz y enviar datos a un servidor externo. Esto es especialmente peligroso en páginas de cuentas personales, servicios internos y paneles de administración donde hay datos sensibles.

Si el usuario ya está autenticado, el navegador sigue considerando el sitio como confiable y puede enviar automáticamente los datos de sesión con las solicitudes. Esto permite que el script malicioso inicie acciones en nombre de la víctima, incluso si el identificador de sesión está protegido contra lectura directa.

Suplantación de la interfaz del sitio

XSS permite modificar el DOM de la página, por lo que el atacante puede agregar nuevos elementos o reemplazar los existentes. Por ejemplo, se puede mostrar una ventana de inicio de sesión falsa, solicitar al usuario que vuelva a introducir su contraseña o proporcionar un botón que lleve a otra página.

Esta suplantación es especialmente peligrosa porque ocurre en el dominio real. El usuario ve la dirección habitual y puede no notar que parte de la interfaz fue creada por el script inyectado.

Mediante XSS también se pueden cambiar enlaces, ocultar advertencias, modificar el contenido de las páginas o redirigir al usuario a otro sitio. En algunos escenarios, el ataque puede usarse como etapa adicional de phishing.

¿Por qué XSS es peligroso incluso en un sitio con HTTPS?

Usar HTTPS no protege contra XSS. HTTPS cifra la conexión entre el navegador y el servidor y ayuda a evitar la lectura o manipulación del tráfico en tránsito, pero no verifica si el JavaScript en la página es seguro.

Si el servidor de un sitio legítimo ha generado la página con un script inyectado o el código del cliente ha creado un DOM vulnerable, el navegador recibirá estos datos a través de una conexión HTTPS totalmente protegida y los ejecutará igualmente.

Esta es la diferencia clave entre XSS y la interceptación de tráfico. En un ataque de "hombre en el medio" (MITM), el atacante intenta intervenir en la comunicación, mientras que en XSS el código malicioso está dentro de la página confiable. Puedes leer más sobre este mecanismo en el artículo sobre qué es un ataque MITM y cómo protegerte del hombre en el medio.

¿Cómo proteger tu sitio contra XSS?

La protección frente al cross-site scripting se basa en un principio: los datos que provienen del usuario o de una fuente externa no deben considerarse automáticamente seguros. La aplicación debe controlar exactamente dónde se insertan y cómo los interpretará el navegador.

No basta con una única comprobación. Una protección sólida combina el escape correcto de las salidas, el manejo seguro del DOM, restricciones para la ejecución de scripts y medidas adicionales para proteger las sesiones.

Escape de salida

La principal defensa contra XSS es mostrar los datos del usuario como texto, no como código HTML. Si alguien introduce un comentario, un nombre o una búsqueda, el navegador debe interpretar los caracteres especiales como parte del texto, no como elementos de marcado.

El método de escape depende del contexto: los datos en HTML, atributos, URLs o cadenas JavaScript requieren tratamientos diferentes. El error ocurre cuando la aplicación usa el mismo método para todos los casos o inserta valores sin procesar directamente en la página.

Los motores de plantillas y frameworks modernos suelen escapar la salida automáticamente, pero la protección puede desaparecer si el desarrollador la desactiva o inserta manualmente HTML sin procesar.

Validación y limpieza de datos

La validación ayuda a limitar el formato aceptable de los datos. Por ejemplo, un campo de edad no debe aceptar marcado HTML, y el nombre de un archivo no debería permitir cualquier conjunto de instrucciones.

Si la aplicación realmente necesita aceptar HTML (por ejemplo, en un editor de artículos o comentarios con formato), prohibir caracteres especiales no es suficiente. En estos casos se utiliza la limpieza del contenido: solo se permiten ciertas etiquetas y atributos seguros, y los elementos potencialmente peligrosos se eliminan.

No obstante, filtrar la entrada no sustituye al escape seguro de la salida. Incluso los datos correctamente validados pueden acabar en otro contexto, así que la protección debe aplicarse justo en el punto en que la información se inserta en la página.

Content Security Policy y manejo seguro del DOM

Un nivel adicional de protección es la Content Security Policy (CSP). Permite al sitio definir de dónde se puede cargar y ejecutar JavaScript, limitando la ejecución de scripts no autorizados.

Una CSP bien configurada puede reducir significativamente las consecuencias de un XSS, pero no debe usarse en vez de corregir la vulnerabilidad. Si la aplicación sigue insertando datos del usuario de forma insegura, el problema persiste.

Hay que prestar atención al JavaScript del lado del cliente. Para mostrar texto ordinario, es preferible usar operaciones como textContent en vez de métodos que interpretan la cadena como HTML. Métodos como innerHTML solo deben usarse cuando el desarrollador controla exactamente el contenido o lo ha limpiado previamente.

Protección de cookies y sesiones

Aun si no se logra eliminar completamente el XSS, se puede reducir el daño. Para las cookies de sesión, se debe usar HttpOnly, que impide que JavaScript acceda directamente a su contenido.

El atributo Secure limita el envío de cookies a conexiones HTTPS, y SameSite ayuda a controlar el envío de cookies en solicitudes desde otros sitios. Estos mecanismos no eliminan la XSS, pero dificultan el robo o abuso de la sesión.

En la práctica, la protección eficaz es multinivel: los datos se escapan antes de mostrarse, el HTML potencialmente peligroso se limpia, el código del cliente evita operaciones inseguras con el DOM, la CSP limita la ejecución de scripts y las cookies están protegidas en el navegador.

Conclusión

Un ataque XSS ocurre cuando el sitio permite que datos no confiables se conviertan en código ejecutable en el navegador del usuario. El JavaScript malicioso puede llegar a la página a través de datos guardados, parámetros de consulta o un manejo inseguro del DOM, por lo que Stored XSS, Reflected XSS y DOM XSS requieren enfoques diferentes para su detección.

La principal defensa es no mezclar datos del usuario con HTML o JavaScript sin un procesamiento seguro. Escape de salida, limpieza del HTML permitido, manejo cuidadoso del DOM, Content Security Policy y cookies protegidas deben emplearse en conjunto. Cuanto antes la aplicación web separe los datos del código ejecutable, menor será la probabilidad de que un simple campo de entrada se convierta en un punto de ataque XSS.

Etiquetas:

xss
seguridad web
cross-site scripting
vulnerabilidades
protección web
ataques informáticos
robos de sesión
content security policy

Artículos Similares