martes, octubre 15, 2019

Google Chrome forzará la política de SameSite=Lax para proteger tus cookies contra los ataques CSRF

Los ataques Client-Side en los navegadores de Internet han ido disminuyendo un poco, pero solo un poco, debido a la cantidad de mejoras de seguridad que se han ido añadiendo para fortificar el navegador. Por desgracia, no siempre son entendidas todas las protecciones por todos los arquitectos de sitios web, ni por supuesto son configuradas en todas las aplicaciones web que visitas. Un ejemplo de ello son las políticas CSP (Content Security Policies) que tan pocos sitios aún configuran, o la política SameSite que Google Chrome ha optado por forzar por defecto.

Figura 1: Google Chrome forzará la política de SameSite=Lax
para proteger tus cookies contra los ataques CSRF

Para entender su funcionamiento hay que ver cuál es el origen de dicha política de seguridad, entendiendo cuáles son los ataques que intentan bloquear. Para ello, la recomendación es que te leas y estudies en detalle el libro de Hacking Web Applications: Cliente-Side Attacks que explica en detalle ataques como XSS, CSRF, CSSP, SSRF, XSPA & SSJS que escribió Enrique Rando (y con el que también puedes contactar vía MyPublicInbox)

Figura 2: Libro de Hacking Web Applications: Client-Side Attacks

El ataque en concreto que busca mitigar el uso de la política SameSite es el de Cross-Site Request Forguery o XSRF, utilizado para forzar acciones en aplicaciones web hechas por usuarios sin que estos sean conscientes, como vimos en votaciones por Twitter donde gente se aprovechaba de este bug para conseguir mejor posición.

CSRF en un minuto

Supongamos que un usuario tiene abierta la página de su aplicación web para ver sus fotografías, donde puede gestionarlas con unos botones de acción que envían por GET la acción. Por ejemplo, para borrar la foto podía ser algo como.
https://www.miweb.com/gestionarfoto.PHP?id=111&accion=eliminar
Lógicamente, esta acción estaría protegida por una cookie de sesión, lo que hace que si alguien conoce ese enlace, pero no tiene iniciada una sesión válida en miweb.com no enviaría la cookie correcta al servidor y por tanto no se podría ejecutar.

Figura 3: Gmail fue afectado por ataques CSRF en sus inicios

Los ataques CSRF se basan en conseguir que sea la víctima del ataque con una sesión iniciada la que envíe esa petición. Para ello el atacante solo necesita saber cuál es la URL que desea ejecutar y hacérsela llegar a la víctima para que ella voluntariamente mediante un engaño haga clic en ese enlace o involuntariamente mediante una vulnerabilidad en cliente que permita forzar la navegación de la víctima a esa URL. Así de sencillo.

¿Cómo protegernos de los ataques CSRF?

Las aproximaciones para evitar este tipo de ataques han sido varias. Primero, poner el envío de acciones como estas en métodos GET no parece la mejor de las ideas. Al ser una URL toda la información GET queda registrada, así que las aplicaciones modernas utilizan más el método POST para evitar que sea tan fácil de capturar e invocar una acción con solo conocer una URL, eso quita gran cantidad de ataques XSS, que por otro lado son mitigados también con los filtros Anti-XSS en los navegadores.

La segunda de las opciones se basa en hacer que la URL por GET no sea tan predecible, para lo que se crean los tokens Anti-CSRF que se añaden en las páginas autorizadas para poner un enlace de este tipo. Es decir, imaginemos que tenemos una herramienta de administración que tiene un panel para pintar la opción de borrar la imagen. Antes de pintarse esa opción, se solicita desde la página web unos tokens Anti-CSRF al backend, y este los entrega a esa URL del panel. Si alguien quiere invocar la URL de borrar, tiene que conocer esos tokens. Si no, el backend lo desecha.

Figura 4: Ejemplo de token Anti-CSRF en OWASP

Es decir, en la petición POST, o en la GET si así fuera, se añaden los tokens CSRF y se evita que el atacante sea capaz de predecirlos. Por supuesto, es necesario que el backend los compruebe, porque hay muchas webs que los añaden pero no los comprueban en el servidor, lo que hace que poniendo cualquier valor, cuele.

La última protección es evitar que vaya la cookie de sesión pegada a la petición. Es decir, evitar que el navegador envíe la cookie de sesión autenticada al servidor si detecta cualquier problema. Y esto es lo que evita la política de SameSite.

Protección de cookies

Como sabéis, el servidor puede establecer que una cookie que él ha generado la entregue el navegador solo a un determinado dominio, a un determinado path, solo bajo métodos HTTP, y bajo conexiones seguras. Son los famosos flags HTTPOnly, Secure y Path. Esto haría que fuera mucho más difícil robar cookies en ataques de Session Hijacking usando JavaScript o suplantación de servidores en ataques de phishing.
Set-Cookie: Elladodelmal=1; Path=/; HTTPOnly; Secure;
Pero no evitan ningún ataque CSRF, en el que el problema es que la petición al backend se hace desde otra pestaña del navegador. Es decir, desde otro origen distinto al que tiene la sesión abierta. Para ello, se creo la política SameSite. Es decir, si la cookie no se ha creado en esa pestaña, a pesar de que se haga un POST al dominio que creo la cookie, el navegador no debería sacarla del Cookie Jar y enviarla. 

Para eso, en la creación de la cookie se añade la política SameSite y el nivel de restricción, que puede ser Strict o Lax. El primero le dice al navegador que bloquee el envío de la cookie desde otra pestaña sea cuál sea el método HTTP que esté utilizando, mientras que con Lax se permite enviar la cookie si el método es GET.
Set-Cookie: Elladodelmal=1; Path=/; HTTPOnly; Secure; SameSite=Strict;
Esto es así, porque muchas aplicaciones web - especialmente redes sociales - viven de referencias en sitios de terceros y exigiría que el usuario tuviera que iniciar sesión cada vez que hiciera un clic en un enlace. Los que tienen esa forma de funcionar, las acciones importantes las configuran siempre por POST y dejan el método GET para eso, para navegaciones internas entre contenidos. Por eso se creo SameSite=Lax
Set-Cookie: Elladodelmal=1; Path=/; HTTPOnly; Secure; SameSite=Lax;
Pero... no mucha gente ha configurado en sus cookies la política Same-Site, así que Google Chrome ha optado por forzarlo de la siguiente manera.

Google Chrome Same-Site-By-Default-Cookies

A partir de la versión de Google Chrome 78 estará activada la opción que está disponible en modo test desde Google Chrome 76 que, si una cookie no tiene la política SameSite, por defecto será como si llevara la opción de SameSite=Lax. Por lo que puede que si tu web utiliza URLs GET sin SameSite para administrar cosas, tal vez te dejen de funcionar comportamientos que son comunes en tus usuarios.

Figura 5: Flags en Google Chrome 77

Lo suyo es que tengas en mente por qué se utiliza SameSite=Lax y veas si puedes mejorar la seguridad de tu web, pero si no, que sepas que Google Chrome va a forzarlo por defecto. Siempre puedes entrar en Google Chrome, y en los flags de configuración cambiar el valor de la opción Same-Site-By-Deafult-Cookies y Deshabilitarlo, pero lo mejor sería que revisaras tu web.

Saludos Malignos!

Autor: Chema Alonso (Contactar con Chema Alonso)

No hay comentarios:

Publicar un comentario