Cross-site scripting (XSS)

12/12/2022

Introducción

El acceso a los sitios web es una actividad común de todos los días, se utiliza para realizar actividades personales, laborales o comerciales. Cuando se ingresa información para obtener el uso de un servicio, como del correo electrónico, banca en línea, compra de productos, entre otros, se establece una interacción dinámica. Dependiendo del valor del dato que se está ingresando en el sitio web, se obtendrá una respuesta diferenciada.

Sin embargo, en muchos sitios web estos datos de entrada no se validan adecuadamente, por lo que hacen que tales sistemas sean vulnerables a secuencias de comandos entre sitios. Este tipo de vulnerabilidades son un problema de seguridad de la información para sitios y usuarios web, fueron descubiertas en la década de los 90 en los primeros días de la aparición de la World Wide Web y se trata de una de las más comunes y peligrosas de las que afectan a los sitios web.

Debido a la relevancia de dicha vulnerabilidad (top ten  de OWASP) [1], el presente trabajo se enfoca en su definición, se comenta en qué consiste, los estudios más destacados, así como la forma en que se pueden realizar diversas pruebas para identificar si algún sitio web la está presentando y se proporcionan algunas sugerencias para su mitigación.

Finalmente se indica que el presente artículo es con fines académicos con el objetivo de hacer una identificación, prevención y mitigación del tipo de ataque XSS.

Objetivo

Describir el tipo de ataque denominado secuencias de comandos entre sitios (XSS), su caracterización y las formas en que puede ser detectado con el fin de mitigarlo.

Desarrollo

¿Qué es XSS?

Las secuencias de comandos entre sitios o XSS como se le conoce en inglés (de Cross-site scripting), es un tipo de ataque que consiste en la inyección de código malicioso en los sitios web para modificar su comportamiento y obtener información valiosa alojada en el sitio y/o perteneciente al usuario.

¿Cómo se presenta el XSS?

Como ya se dijo, el XSS es un tipo de ataque de inyección de código malicioso que hace uso de vulnerabilidades en los sitios o aplicaciones web, cuyos usuarios tienen confianza y les parecen benignos. A partir de que esta confianza se ha establecido, el atacante usa las vías que la aplicación ofrece a sus usuarios para ingresar información pero con el fin de enviar código malicioso a otros usuarios, frecuentemente como un script del lado del navegador cuya ejecución se considera adecuada por parte del usuario pues la considera proveniente de una fuente confiable.

¿En qué consiste el XSS?

El atacante envía un código malicioso desde una aplicación considerada confiable. Dicho código puede acceder a las cookies, tokens de sesión y otra información contenida en el navegador para ser utilizada desde el sitio vulnerado. Los códigos maliciosos pueden inclusive establecer procesos de reescritura del contenido HTML.

Hay varias formas de caracterizar esta vulnerabilidad. A continuación se definen tres tipos principales de ataques de secuencias de comandos entre sitios [2,3]:

  • Tipo I, reflejado o no persistente: ocurre cuando una aplicación regresa un mensaje de error, el resultado de una búsqueda o cualquier respuesta que incluya parte o toda la entrada provista por el usuario como parte de la petición al servidor, sin que dichos datos sean asegurados para su despliegue en el navegador y sin que se almacenen permanentemente (en algunos casos, los datos del usuario ni siquiera dejan el propio navegador utilizado).
  • Tipo II, almacenado o persistente: consiste en que los datos del usuario son almacenados en el servidor destino (una base de datos,  foro, log, comentario, y otros) pero al ser recuperados, no son asegurados para su despliegue en el navegador. De igual manera, con el advenimiento del HTML5, los datos pueden ser almacenados de forma permanente en el propio navegador pero no en el servidor destino.
  • Tipo 0, basado en DOM: todo el flujo de dato se realiza en el propio navegador del usuario víctima, vía el Modelo de Objetos del Documento (DOM)[4], es decir, los datos nunca dejan el navegador.

Pero como se puede ver, en realidad hay traslapes en la definición de los tipos anteriores. Por ello, otra clasificación atiende tanto la persistencia de datos, como el lugar donde se realiza el ataque[3]:

  • Del lado del servidor: la vulnerabilidad ocurre en el código del servidor, el navegador simplemente despliega la información y ejecuta el código que se le proporciona como respuesta. Como resultado, en este ataque los datos de un usuario no autenticado son incluidos en una respuesta HTTP generada por el servidor. La fuente de datos puede ser el servidor o algún repositorio. Incluye a los tipos I y II.
  • Del lado del cliente: ocurre cuando datos de un usuario no autenticado se usan para actualizar el DOM de una llamada JavaScript insegura, es decir, aquella que puede ser usada para introducir código JavaScript válido en el DOM proveniente de la misma página o bien de un servidor, y sea vía una invocación de JavaScript Asíncrono + XML (AJAX) o la descarga de una página. Incluye los tipos I y II.

En la Tabla 1 se muestra una matriz con las definiciones anteriores atendiendo a los aspectos mencionados: dónde ocurre el ataque y la persistencia del almacenamiento.

XSS Servidor Cliente
Almacenado XSS almacenado en el servidor XSS almacenado en el cliente
Reflejado XSS reflejado en el servidor XSS reflejado en el cliente

Tabla 1. Tipos de vulnerabilidad XSS (Adaptado de [3])

Estudios más destacados

Las investigaciones en torno al tipo de ataque de secuencias de comandos entre sitios se agrupan en dos áreas principales[5]: ataque y defensa, que abarcan aspectos como la prevención, la detección, predicción, y la implementación de soluciones. En relación a las posibles alternativas para lidiar con esta vulnerabilidad, los investigadores se decantan tanto por realizar[5]:

  • Análisis estático: revisión de código fuente para detectar fallas con diversas técnicas como algoritmos genéticos o análisis sintácticos de cadenas, ejecución simbólica de código y análisis de flujo de datos, entre otros.
  • Análisis dinámico: se enfoca en analizar la aplicación mientras se está ejecutando, ya sea mediante pruebas de caja negra, análisis de flujo de datos, monitoreo y filtrado, y otros.
  • Aseguramiento de código: promueve el uso de guías y reglas de desarrollo, con técnicas como Type Systems y Embedded Language Encapsulation Type, así como bibliotecas y modelos de objetos, con el fin de asegurar la calidad de códigos y bases de datos.
  • Modelar las vulnerabilidades o los ataques: realizan abstracciones, verificación e inferencia de modelos, modelos evolutivos difusos, validación de entradas, simulación, modelos basados en firmas, URL de un solo uso, conmutación de subdominios, minería de datos, grafos de flujo de control, máquinas de estados finitos, y diversos modelos.
  • Otras técnicas: establecimiento de índices y benchmarkings dedicados a estas vulnerabilidades.

Como se puede ver, las soluciones no son simples y no hay una sola para este tipo de ataque. El análisis dinámico es una de las estrategias de mitigación más reputadas tanto en la academia como en la industria.

En el apartado siguiente se muestran ejemplos de algunas formas en que se puede identificar este tipo de ataque y las medidas generales para mitigarlo.

¿Cómo hacer pruebas para identificar XSS en mi sitio web?

Para identificar si una página web es vulnerable a XSS se pueden realizar algunas pruebas simples. Existen páginas web y repositorios en los que la comunidad ha ido integrando un compendio de payloads para probar vulnerabilidades de XSS, comúnmente estas listas contemplan los tres tipos de ataques de XSS. Una vez introducido el payload existen cuatro posibilidades principales:

  • En caso de que la cadena se visualice de manera completa, existe una gran posibilidad de que el sitio web no sea vulnerable a un ataque de XSS.
  • En el caso de que la cadena se visualice incompleta, ya sea sin caracteres especiales como <>();/ o sin etiquetas o alguna palabra, es posible que antes de procesar la cadena, esta se pase por alguna función de filtrado de caracteres o palabras clave con el fin de evitar diversos ataques, entre ellos el XSS. En este caso se puede proceder a revisar el filtrado para detectar fallos, para esto se puede reescribir el mismo payload con diferentes caracteres o buscar payloads diferentes.
  • Existen plugins o tecnologías diversas que detectan cuando se está intentando ejecutar una acción maliciosa como una inyección XSS o SQL. Por lo que es posible que simplemente se obtenga un mensaje de error.
  • Finalmente, si no existiera ninguna protección contra ataques XSS esto se vería reflejado, ya que realizará la acción inyectada; para poder visualizarlo de una manera rápida normalmente se realiza la inyección para ejecutar la función alert, ya que se muestra como un cuadro de diálogo pop up y se identifica de inmediato la vulnerabilidad.
 

XSS reflejado

Para ejemplificar este tipo de ataque se utilizará el siguiente sitio web https://xss-game.appspot.com/level1/frame 

Figura 1. Introducir una cadena de texto.

Como se puede observar existe un campo para introducir una cadena de texto con el propósito de buscarla.

Figura 2. Cadena de texto introducida reflejada en la salida de la página.

Se puede observar que la cadena introducida se refleja en un mensaje dentro de la misma página, por lo que se pueden realizar pruebas para determinar si existe XSS. 

Una prueba básica es introducir el siguiente payload: 

<script>alert(1);</script>

Figura 3. Ejecución del payload.

Como se puede observar se obtiene el cuadro de diálogo con el mensaje indicado, en este caso, el número 1.

XSS Persistente

Para ejemplificar este tipo de ataque se utilizará el siguiente sitio web https://xss-game.appspot.com/level2/frame.

Figura 4. Sitio web con mensajes persistentes.

Como se puede observar, esta es una especie de chat, este tipo de prueba se considera persistente ya que si se realiza un post es posible recargar la página y este seguirá apareciendo.

Para este tipo de acciones se suele insertar un payload como el siguiente 

<img src="paginaInvalida" onError="alert(1)">

Ya que este no busca ejecutarse de inmediato en el momento que carga la página, sino que requiere la condición de que la imagen que se intenta mandar a llamar no puede insertarse correctamente, por lo que se ejecuta cada vez que la página se recargue.

Figura 5. Ejecución de payload desde mensajes almacenados.

Como se observa en la imagen anterior los mensajes se conservan y ya que la imagen que se intentó importar no existe, se ejecuta la acción mandada a llamar en caso de error y por lo tanto se ejecuta la función alert() con el mensaje “1”.

XSS DOM

Este tipo de prueba es más complicada de comprobar, ya que se basa en gran parte en la interacción con el código de la página, por ejemplo si el valor de algún parámetro se concatena dentro de alguna etiqueta. Es por eso que este tipo de pruebas se crean más a la medida de cada página por lo que, aun cuando una lista de payloads puede contener uno que se adapte a la página, se requieren mayores conocimientos para generar la prueba. 

Herramientas

Existen variados tipos de software enfocados a pruebas de penetración que automatizan la ejecución de payloads en muchos o todos los parámetros que se puedan encontrar dentro de un sitio como acunetix o rapid7, a su vez, para un análisis más informal y superficial, existen otros programas como la extensión XSS de la Chrome web store, que permiten realizar intentos de inyección de scripts para detectar esta vulnerabilidad.

Prevención y mitigación de XSS

Para lograr prevenir o mitigar exitosamente los ataques XSS, es necesario separar y sanitizar los datos que no son de confianza, del contenido original del sitio web. Para esto se pueden realizar las siguientes acciones:

  • Actualmente existen múltiples frameworks diseñados para prevenir el ataque XSS por lo que dependiendo de la tecnología que se esté utilizando se recomienda implementar también un framework compatible que sirva para este propósito.
  • Validar y sanitizar todos los inputs dentro del sitio web.
  • Codificar todas las salidas dentro del sitio, es decir, sustituir caracteres de toda aquella cadena que desee mostrarse en pantalla por ejemplo sustituir los símbolos de menor y mayor que por sus codificaciones correspondientes para html: &lt; y &gt; respectivamente.
  • A pesar de que no se considera como una medida definitiva se considera como una buena práctica y un apoyo para las otras medidas el habilitar la cabecera Content Security Policy (CSP).
  • Mantener el software actualizado a la última versión estable, para mantener implementados los últimos parches de seguridad.
 

Conclusiones

El ataque de secuencias de comandos entre sitios o XSS aprovecha las vulnerabilidades y afecta a sitios y aplicaciones web y, dado el uso extensivo de estos sistemas, a una creciente comunidad usuaria de servicios digitales. Por ello, se recomienda que los administradores y  desarrolladores de sitios web tomen en cuenta las técnicas para su prevención, identificación y mitigación. 

Dichas recomendaciones incluyen la implementación de frameworks anti ataques XSS, la sanitización de inputs, la codificación de outputs y la implementación de la cabecera CSP. 

Finalmente, para mejorar la seguridad de un sitio web se recomienda realizar periódicamente pruebas de penetración por un equipo cualificado y mitigar adecuadamente todos aquellos hallazgos que se hayan detectado.

 

Referencias

[2] Cross Site Scripting (XSS). OWASP Foundation  https://owasp.org/www-community/attacks/xss/ 
[3] Types of Site Scripting (XSS). OWASP Foundation
[4] Document Object Model (DOM) - Web APIs | MDN (mozilla.org)
[5] Isatou Hydara, Abu Bakar Md. Sultan, Hazura Zulzalil, Novia Admodisastro, Current state of research on cross-site scripting (XSS) – A systematic literature review, Information and Software Technology, Volume 58, 2015, Pages 170-186, ISSN 0950-5849, https://doi.org/10.1016/j.infsof.2014.07.010 
[9] Pruebas de concepto. https://xss-game.appspot.com/ 
 
 
 
 

La Coordinación de Seguridad de la Información/UNAM-CERT agradece el apoyo en la elaboración o traducción y revisión de este Documento a:

  • Esther Lugo Rojas (esther dot lugo at cert dot unam dot mx)
  • César Alejandro Varela Cruz (cesar dot varela at cert dot unam dot mx)
 

Liberación original: Lunes, 12 Diciembre 2022