Volver |

XSS

Introducción

XSS (Cross Site Scripting) es un tipo de vulnerabilidad en aplicaciones web que permite cambiar el comportamiento de la aplicación “inyectando” código JavaScript, HTML o cualquier otra tecnología del lado del cliente.

 

Enlaces de interés:

https://github.com/LabSis/secure-pocs

Tipos

  • XSS indirecto o reflejado.

  • XSS persistente o almacenado.

  • XSS basados en DOM.

XSS Indirecto o Reflejado

En este tipo de XSS, la aplicación utiliza datos ingresados por el usuario sin ser validados correctamente y ejecuta el código asumiendo que es parte de la salida HTML.Un atacante podría inyectar como parámetro un código malicioso y de esta manera ejecutar dicho código en su objetivo. Por ejemplo se puede manipular un parámetro GET de una determinada aplicación web y mandar la url a la víctima para que la misma abra el enlace y ejecute el código malicioso. Cabe aclarar que este ataque es de carácter temporal, es decir, no persiste en la aplicación, solo refleja el parámetro en cuestión pero no lo guarda.

Para esclarecer, veamos un ejemplo:

Supongamos una página que tiene un buscador, en este caso de libros, y el usuario en vez de ingresar el título de un libro ingresa código JavaScript. Desarrollaremos una simple aplicación php para demostrar lo que ocurre al ejecutar el caso descrito.

Código fuente de la página vulnerable:

<html>
   <head>
       <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
       <title>XSS Indirecto</title>
   </head>
   <body>
       <form action="#" method="GET">
           <label>Buscar libro:</label>
           <input type="text" size="20" name="txtLibro">
           <input type="submit" value="Buscar">
       </form>
       <?php
       if(isset($_GET['txtLibro'])){
           $html = "<h2>No se ha encontrado el libro " . $_GET['txtLibro'] . "</h2>";
           echo $html;
       }
       ?>
   </body>
</html>

 

Es una página muy simple con el fin de mostrar qué ocurre si la variable $_GET['txtLibro'] en vez de contener un nombre de un libro, contiene código JavaScript, y luego mostramos dicha variable con el comando echo.

Si por ejemplo, ingresamos el siguiente código JavaScript:

<script> alert(“XSS Indirecto o Reflejado”); </script>

Ahora si presionamos en buscar, observamos que se ejecuta el código enviado.

El código retornado por el servidor es:

<!DOCTYPE html><html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>XSS Indirecto</title>
</head>
<body>
    <form action="#" method="GET">
        <label>Buscar libro:</label>
        <input type="text" size="20" name="txtLibro">
        <input type="submit" value="Buscar">
    </form>
    <h2>No se ha encontrado el libro <script> alert("XSS Indirecto o Reflejado"); </script></h2>    
</body>
</html>

Como la página de php muestra directamente la cadena enviada por el usuario, y en este caso es un simple script, el navegador lo toma como tal y lo ejecuta.

La técnica de XSS Indirecto o Reflejado suele utilizarse cuando la petición al servidor es mediante el método GET, es decir, que las variables van en la URL, de esta forma se puede pasarle a otra persona una URL de un sitio web que admita XSS Indirecto y el código JavaScript. Entonces si la víctima abre el link se ejecuta el script introducido por el atacante.

 

Aclaración: Existen navegadores que toman medidas contra este ataque, identifica el vector de ataque y no ejecuta el script.

 

XSS persistente o almacenado

En este caso, el código malicioso se almacena en el servidor web y es ejecutado cada vez que se accede a una página desde un navegador. Entonces si existe una aplicación que guarda el contenido de un usuario en el servidor sin llevar a cabo ningún método de control, se puede insertar el código malicioso ahí y cada vez que un usuario ingrese a la página en cuestión será víctima del ataque.

Pensemos por ejemplo en una aplicación que posee un foro. Cada intervención dentro del mismo se guardará en la base de datos. Si las intervenciones no se tratan correctamente, filtrando y validando el contenido, podrían ser vectores de ataque que persistirán en el servidor y se ejecutarán cada vez que alguien ingrese al tema del foro en donde fue insertado el vector.

 

Enlaces de interés:

https://github.com/LabSis/secure-pocs/tree/master/xss_persistente

XSS basado en DOM

En este caso, a diferencia de los demás, el daño se produce a través de los scripts que están en el lado del cliente que incorporan al DOM algún parámetro en particular por ejemplo, algún parámetro especificado en la url.

La respuesta HTTP no cambia pero en el lado del cliente existe código que ejecuta el código malicioso.

Se volvió más popular con el creciente uso de frameworks para javascript en donde la comunicación con el servidor se da generalmente a través de una API. También se aplica a páginas estáticas.

 

Ejemplo:

Supongamos que el siguiente código es utilizado para crear un formulario para elegir el país de residencia de una persona y el mismo marca la opción por defecto que retorna el servidor.

 

<label>Selecciona tu país de residencia:</label><select>   <script>       document.write("<OPTION    value=1>"+document.location.href.substring(document.location.href.indexOf("default=")+8)+"</OPTION>");       document.write("<OPTION value=2>Brasil</OPTION>");       document.write("<OPTION value=3>Bolivia</OPTION>");       document.write("<OPTION value=4>Perú</OPTION>");   </script></select>

La página normalmente, es utilizada como:

http://www.sitio-vulnerable/selecciona-pais.html?default=Argentina

Un ataque XSS basado en DOM podría ser algo como:

http://www.sitio-vulnerable/selecciona-pais.html?default=<script>alert(document.cookie)</script>

De esta manera el código malicioso se inyectará a través del código javascript.Analizando, es similar al XSS reflejado con la diferencia de que el XSS basado en DOM se ejecuta por el código utilizado en el cliente y no viene inyectado en la respuesta HTTP como sucede en el XSS reflejado.

Defensa

Para defendernos de esta vulnerabilidad debemos controlar y filtrar los parámetros con los que estamos trabajando. Pero no solo las entradas, sino también la salidas en caso de un servidor.

Existen una serie de recomendaciones para prevenir este ataque (OWASP):

  • Validar datos de requerimientos HTTP no confiables en el contexto de la salida de HTML (cuerpo, atributos, JavaScript, CSS, o URL) para XSS reflejado y persistente.

  • Aplicar codificación sensitiva al contexto cuando se modifica el documento en el navegador en el lado cliente, ayuda a prevevenir DOM XSS.

  • Filtrar parámetros de entrada y de salida tanto en el servidor como en el cliente.

  • Habilitar una Política de Seguridad de Contenido Content Security Policy (CSP) es una defensa profunda para la mitigación de vulnerabilidades XSS, asumiendo que no hay otras vulnerabilidades que permitan colocar código malicioso vía inclusión de archivos locales como sobreescritura de caminos, o bibliotecas vulnerables de fuentes conocidas, como redes de distribución de contenidos (CDN) o bibliotecas locales.

Para más información sobre la defensa, ver: https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/DOM_based_XSS_Prevention_Cheat_Sheet.md

 

Cómo bypassear filtros para ejecutar código XSS

Para poder intentar bypassear los filtros de un parámetro que estamos testeando, en el siguiente link se muestra una lista de posibilidades a probar que pueden funcionar o no.

Cabe destacar que algunas de ellas contienen una string genérica la cual puede ser cambiada para ejecutar el script que uno desee.

https://gist.github.com/rvrsh3ll/09a8b933291f9f98e8ec 

 

En este artículo participaron: