Tema 13

13. Cross-Site Scripting (XSS), CSRF y vulnerabilidades del navegador

Muchas vulnerabilidades web no comprometen directamente al servidor en primer lugar, sino al navegador de la víctima. Cuando una aplicación permite ejecutar código no previsto en el cliente o abusar de la confianza que el navegador ya tiene en un sitio, el atacante puede robar sesiones, manipular acciones, alterar la interfaz o utilizar al usuario autenticado como canal de ataque.

Objetivo Entender cómo se ataca la confianza del navegador
Enfoque XSS, CSRF, contexto del cliente y defensa
Resultado Reconocer vulnerabilidades que impactan directamente en la sesión del usuario

13.1 Introducción

Hasta ahora vimos varias categorías que afectan sobre todo al servidor, al diseño o a la infraestructura. En este tema nos enfocaremos en vulnerabilidades donde el navegador de la víctima pasa a ser un actor clave del ataque. El hecho de que una persona visite una página, tenga una sesión activa o confíe en una interfaz puede convertirse en la base del compromiso.

El navegador no es un simple visor pasivo. Ejecuta JavaScript, almacena cookies, interpreta HTML, sigue redirecciones, envía automáticamente credenciales a ciertos orígenes y mantiene relaciones de confianza con los sitios donde el usuario inició sesión. Si la aplicación no controla adecuadamente qué código se ejecuta o qué solicitudes pueden inducirse desde ese contexto, el impacto puede ser severo.

Las dos categorías principales que abordaremos aquí son XSS y CSRF, además de algunas ideas más amplias sobre vulnerabilidades del lado cliente y del navegador.

13.2 El navegador como superficie de ataque

Cuando el usuario interactúa con una aplicación web, el navegador se convierte en un entorno de ejecución y almacenamiento con mucho valor para un atacante. Allí pueden vivir:

  • Cookies de sesión.
  • Tokens de autenticación.
  • Datos renderizados de la cuenta.
  • Estado de la interfaz y acciones del usuario.
  • Capacidad de enviar solicitudes al sitio autenticado.

Por eso una vulnerabilidad del lado cliente no debe subestimarse. Aunque no comprometa directamente el servidor, puede permitir secuestro de sesión, robo de información, fraude o abuso del contexto autenticado de la víctima.

13.3 Qué es Cross-Site Scripting (XSS)

XSS ocurre cuando la aplicación permite que contenido controlado por un atacante sea interpretado por el navegador como código activo dentro del contexto del sitio vulnerable. En lugar de tratar ese contenido como texto o dato, el navegador lo ejecuta o lo incorpora al DOM con privilegios del origen legítimo.

Esto le da al atacante una ventaja poderosa: su código corre como si perteneciera al sitio confiable desde la perspectiva del navegador.

XSS no es solo "mostrar un script". Es permitir que el atacante ejecute lógica dentro del contexto de confianza que el navegador asigna a la aplicación.

13.4 Impacto general de XSS

Una explotación XSS puede tener consecuencias muy diversas según el contexto de la aplicación y lo que la víctima tenga abierto o autenticado.

  • Robo de información mostrada en pantalla.
  • Abuso de la sesión actual del usuario.
  • Realización de acciones en nombre de la víctima.
  • Manipulación visual de la interfaz para fraude o phishing.
  • Lectura o modificación de ciertos datos accesibles desde el cliente.
  • Pivoting hacia otras funciones de la aplicación.

En cuentas privilegiadas, el impacto puede ser especialmente severo.

13.5 XSS reflejado

El XSS reflejado ocurre cuando la carga maliciosa enviada por el atacante vuelve en la respuesta inmediata de la aplicación y es interpretada por el navegador. Suele aparecer en parámetros de búsqueda, mensajes, filtros o páginas de error que reflejan entrada sin escape adecuado.

Este tipo de XSS generalmente requiere que la víctima visite una URL o interacción preparada por el atacante, pero sigue siendo peligroso porque puede usarse en campañas dirigidas o combinadas con ingeniería social.

13.6 XSS almacenado

El XSS almacenado ocurre cuando el contenido malicioso se guarda en la aplicación y luego se entrega a otros usuarios. Puede aparecer en comentarios, perfiles, mensajes, publicaciones, tickets de soporte, campos administrativos o cualquier dato persistente que luego se renderice sin protección adecuada.

Este tipo de XSS suele ser más grave porque no depende de una URL puntual: la carga queda alojada en la propia aplicación y afecta a quienes acceden luego al contenido.

13.7 XSS basado en DOM

En el XSS basado en DOM, el problema aparece del lado cliente cuando JavaScript manipula valores no confiables y los inserta en el documento de forma insegura. En estos casos, la respuesta del servidor puede ser relativamente "limpia", pero el código del navegador termina construyendo un DOM vulnerable a partir de datos controlados por el usuario o por la URL.

Este escenario es especialmente relevante en aplicaciones con mucho JavaScript, SPA y lógica cliente compleja.

13.8 Por qué XSS sigue siendo tan frecuente

La persistencia de XSS se explica por varios factores:

  • Interfaz web compleja con múltiples contextos de renderizado.
  • Uso intensivo de JavaScript y manipulación dinámica del DOM.
  • Confusión entre sanitización, validación y encoding.
  • Suposición errónea de que "si el dato viene de mi base, ya es confiable".
  • Frameworks o plantillas usados de forma insegura.

13.9 Contextos de salida: no todo se protege igual

Una de las ideas más importantes para prevenir XSS es entender que la salida debe tratarse según el contexto donde se inserta. No es lo mismo mostrar texto en HTML que incrustarlo en JavaScript, en atributos, en URLs o en estilos.

El error frecuente es aplicar una única "limpieza genérica" y asumir que eso resuelve todo. En realidad, la protección correcta depende del lugar exacto donde el dato será interpretado por el navegador.

13.10 Validación, sanitización y encoding

Estos tres conceptos suelen confundirse:

  • Validación: comprobar si la entrada cumple formato o reglas esperadas.
  • Sanitización: remover o transformar contenido considerado peligroso en ciertos contextos.
  • Encoding de salida: representar los caracteres de modo seguro según el contexto donde se mostrarán.

Para XSS, el encoding de salida correcto suele ser la defensa central, complementado por sanitización estricta cuando el negocio necesita aceptar contenido enriquecido.

13.11 Content Security Policy como defensa adicional

Content Security Policy, CSP, ayuda a restringir qué scripts y recursos puede ejecutar el navegador. No reemplaza una codificación segura, pero sí agrega una capa importante para reducir impacto de ciertos escenarios XSS.

Su valor está en:

  • Limitar orígenes permitidos de scripts.
  • Reducir ejecución arbitraria inline si se diseña correctamente.
  • Dificultar explotación trivial de algunos vectores.

Una CSP mal diseñada o demasiado permisiva aporta poco. Su efectividad depende de implementación coherente con la aplicación real.

13.12 Qué es CSRF

CSRF, Cross-Site Request Forgery, ocurre cuando una aplicación permite que un sitio o contenido externo induzca al navegador de una víctima autenticada a enviar una solicitud no deseada al sitio legítimo. La clave aquí es que el navegador, al confiar en el origen donde el usuario ya tiene sesión, puede enviar automáticamente cookies u otras credenciales asociadas.

En este caso, el atacante no necesita robar la sesión; le alcanza con aprovechar que el navegador de la víctima ya la tiene activa.

13.13 Cómo funciona conceptualmente CSRF

La secuencia típica es:

  1. La víctima tiene sesión iniciada en una aplicación legítima.
  2. Visita un sitio controlado por el atacante o contenido malicioso.
  3. Ese contenido induce una solicitud al sitio legítimo.
  4. El navegador envía la solicitud junto con las credenciales automáticas correspondientes.
  5. Si la aplicación no distingue entre una acción legítima del usuario y una inducida externamente, la operación se ejecuta.

13.14 Qué tipo de acciones suelen ser vulnerables a CSRF

CSRF es especialmente grave en acciones que cambian estado o producen efectos de negocio.

  • Cambio de contraseña o correo.
  • Actualización de perfil.
  • Transferencias o pagos.
  • Creación o borrado de recursos.
  • Operaciones administrativas.

Si la aplicación acepta estas acciones confiando solo en la presencia de la sesión, sin otra señal de legitimidad, el riesgo aumenta mucho.

13.15 XSS y CSRF: diferencias importantes

Vulnerabilidad Idea central
XSS El atacante logra ejecutar o inyectar código en el contexto del sitio
CSRF El atacante induce al navegador a enviar acciones autenticadas no deseadas

Aunque son distintas, se potencian entre sí. Una XSS puede hacer trivial explotar acciones CSRF o directamente saltar defensas adicionales del lado cliente.

13.16 Defensa frente a CSRF

La defensa clásica contra CSRF consiste en asegurar que las solicitudes sensibles incluyan una prueba adicional de legitimidad que un tercero no pueda inducir fácilmente desde otro origen.

Medidas habituales:

  • Tokens anti-CSRF por sesión o por formulario.
  • Uso adecuado de SameSite en cookies.
  • Validación de contexto mediante encabezados esperables como Origin o Referer cuando corresponda.
  • Evitar acciones sensibles por métodos inseguros o por GET.
  • Reautenticación en operaciones críticas.

13.17 El navegador como entorno de confianza parcial

Una idea útil para este tema es que el navegador no es confiable, pero sí mantiene ciertos comportamientos automáticos de confianza entre usuario y sitio. Las cookies se envían, el DOM se interpreta, los scripts se ejecutan según origen y las sesiones persisten. Los ataques del lado cliente intentan precisamente abusar de esos comportamientos.

Por eso la defensa no debe basarse en asumir que el navegador "hará lo correcto", sino en delimitar qué contenido puede ejecutar y qué solicitudes deben considerarse legítimas.

13.18 Otras vulnerabilidades del navegador relacionadas

Además de XSS y CSRF, el ecosistema cliente puede verse afectado por otras debilidades o malas prácticas:

  • Uso inseguro de almacenamiento local para material sensible.
  • Exposición de secretos o datos internos en JavaScript del lado cliente.
  • Dependencia excesiva de controles aplicados solo en frontend.
  • Integración insegura de recursos de terceros.
  • Manipulación visual de interfaz para engaño o phishing interno.

13.19 Señales que justifican revisión

  • La aplicación refleja o renderiza contenido del usuario en múltiples puntos.
  • Existen componentes que insertan HTML dinámico sin controles claros.
  • Hay acciones sensibles ejecutables solo con cookies de sesión.
  • Se usan métodos GET para operaciones que cambian estado.
  • No existe CSP o es extremadamente permisiva.
  • La interfaz depende demasiado de validaciones del lado cliente.

13.20 Ejemplos típicos de esta categoría

  • Campo de comentarios que permite inyectar contenido activo.
  • Parámetro de búsqueda reflejado sin encoding correcto.
  • Código JavaScript que toma valores de la URL y los inserta inseguramente en el DOM.
  • Formulario sensible sin token anti-CSRF.
  • Operación crítica disparable mediante GET desde un sitio externo.
  • Cookies de sesión sin atributos protectores adecuados.

13.21 Buenas prácticas de prevención

La defensa frente a vulnerabilidades del navegador exige combinar varias capas.

  • Aplicar encoding de salida según contexto.
  • Sanitizar de forma estricta cuando se permita contenido enriquecido.
  • Evitar sinks inseguros del lado cliente.
  • Usar CSP como capa adicional bien diseñada.
  • Proteger acciones sensibles con tokens anti-CSRF y cookies adecuadas.
  • No depender del frontend para controles críticos de seguridad.
  • Minimizar exposición de datos y secretos en el cliente.

13.22 Errores frecuentes en la remediación

  • Aplicar una sanitización genérica sin considerar el contexto real de salida.
  • Confiar en filtros superficiales de palabras o etiquetas.
  • Agregar CSP pero dejarla demasiado abierta.
  • Corregir un punto de renderizado y olvidar otros equivalentes.
  • Asumir que SameSite por sí solo elimina todo riesgo CSRF.
  • Usar tokens anti-CSRF inconsistentes o no validarlos realmente.

13.23 Relación con otras vulnerabilidades

Estas fallas se combinan con varias de las categorías anteriores.

  • Con Authentication Failures, si el objetivo es apropiarse de una sesión o actuar como el usuario.
  • Con Broken Access Control, si la víctima autenticada tiene acceso a funciones sensibles.
  • Con Logging Failures, si el abuso del contexto del navegador no queda detectado.
  • Con Security Misconfiguration, si CSP, cookies o cabeceras están mal definidas.

Esto muestra que el navegador no es una capa aislada: es un punto de encuentro entre múltiples decisiones de seguridad.

13.24 Qué debes recordar de este tema

  • XSS permite ejecutar contenido controlado por el atacante en el contexto del sitio vulnerable.
  • CSRF permite inducir solicitudes autenticadas no deseadas usando el navegador de la víctima.
  • El navegador mantiene relaciones de confianza que pueden ser abusadas si la aplicación no se protege bien.
  • La defensa frente a XSS depende en gran medida del encoding de salida correcto según contexto.
  • La defensa frente a CSRF requiere controles adicionales más allá de la simple sesión.
  • CSP y atributos de cookies ayudan, pero no reemplazan diseño seguro.
  • Los controles críticos deben seguir validándose del lado servidor.

13.25 Conclusión

XSS, CSRF y otras vulnerabilidades del navegador muestran que la seguridad web no se limita al backend. El cliente, la sesión y la interfaz también forman parte del sistema de confianza. Si la aplicación permite ejecutar código no previsto o inducir acciones autenticadas sin legitimidad suficiente, el atacante puede convertir al propio usuario en vector de compromiso.

En el próximo tema estudiaremos la subida de archivos, la deserialización insegura aplicada en escenarios prácticos y la ejecución remota, tres áreas donde una entrada aparentemente inocente puede transformarse en ejecución o control sobre el entorno.