Understanding Authentication and Web Storage
Basics of Auth and Web Storage for Hackers
Introducción
Actualmente, es fundamental conocer el funcionamiento de las distintas formas en las que un sitio web puede manejar el proceso de autenticación. A la hora de realizar la autenticación, la misma puede ser stateful (Por ej. Utilizando una Cookie de sesión) o stateless (Por Ej. Usando un token JWT, OAuth, etc).
¿Como funciona una autenticación basada en sesiones (Stateful)?
- El usuario envía sus credenciales (User & Pass).
- El server verifica las credenciales en su DB.
- El server crea una sessionID temporal para el usuario y lo almacena en su DB.
- El server le envía un sessionID al cliente (Normalmente seteando una cookie)
- El cliente debe envíar ese sessionID en todas sus solicitudes al servidor.
- Cada vez que el server recibe estas solicitudes, debe validar que el sessionID sea correcto y permitir el acceso.
- Cuando el usuario se desloguea o transcurre un tiempo determinado de expiración, el server debe borrar el sessionID de su DB y indicarle al cliente que elimine el sessionID que tiene almacenado.
¿Como funciona una autenticación basada en tokens (Stateless)?
- El usuario envía sus credenciales (User & Pass).
- El server verifica las credenciales en su DB.
- El server crea un Access Token temporal y embebe data del usuario en dicho token. Dicho token deben tener un período de validez corto y nunca se almacena en el servidor.
- El server le envía el Access Token al cliente (Normalmente utilizando un header o en el body).
- El cliente almacena el Access Token (Normalmente en el localStorage o sessionStorage).
- El cliente debe envíar ese Access Token en todas sus solicitudes al servidor.
- El server verifica ese Access Token y permite el acceso.
- Cuando el usuario se desloguea o transcurre su tiempo de validez, el Access Token expira y se elimina del lado cliente .
Cookies, localStorage y sessionStorage
Como pudieron observar anteriormente, tanto en las autenticaciones stateful como las stateless es necesario que el cliente pueda almacenar datos para mantener la sesión (Los sessionIDs o los tokens). Existen tres lugares en donde podemos almacenar estos datos, el localStorage, el sessionStorage y las Cookies.
Como se puede observar en el cuadro comparativo anterior, las Cookies son las únicas que se envían automaticamente cuando hacemos una solicitud, es importante saber esto debido a que si a la hora de auditar un sistema, el mismo, no utiliza cookies, no será vulnerable a ataques de Cross-Site Request Forgery (CSRF).
Cookies
Como vimos antes, una cookie simplemente es un lugar en el cual solo disponemos de 4kb para almacenar información, y esta información puede ser tanto para manejar la sessión (Session Cookie) como para personalización o tracking.
Las cookies cuentas con los siguientes atributos a destacar:
- Domain y Path: Indican que la cookie puede ser utilizada en un sitio y una ruta específica.
- Expiration: Indica que la cookie solamente puede ser utilizada hasta que expire.
Las cookies también pueden contar con los siguientes flags a destacar:
- HttpOnly: Este flag indica que esta cookie no puede ser leída por Javascript. Lo que quiere decir que si encontramos una inyección XSS, con la misma NO podremos acceder a dicha cookie.
- Secure: Este flag indica que esta cookie solo puede ser envíada utilizando HTTPS.
- SameSite: Este flag indica que la cookie solo puede ser envíada desde el mismo dominio.
Un punto a tener en cuenta, es que las cookies deben ser protegidas contra los ataques Cross-Site Request Forgery (CSRF) utilizando tokens Anti-CSRF debido a que las mismas se envían automaticamente al realizar una solicitud al servidor.
LocalStorage y SessionStorage (ClientStorage)
Como pudimos ver anteriormente, si utilizamos el localStorage o el sessionStorage nuestra aplicación no será vulnerable a ataques del tipo Cross-Site Request Forgery (CSRF). Además, podemos notar que tenemos mayor espacio para el almacenamiento de la información (5 MB sessionStorage vs. 4 KB Cookie).
Sin embargo, que ocurre con las inyecciones XSS? Tenemos una protección que impida a Javascript acceder al clientStorage?
La respuesta es NO, en caso de que se encuentre una inyección XSS en el sitio, la misma podrá ser utilizada para acceder al clientStorage. A continuación, podemos ver como agregar, eliminar o ver un item:
<script>
localStorage.setItem('name','Bob'); //Agrego un Item al localStorage
localStorage.removeItem('name'); //Elimino un Item del localStorage
console.log(localStorage.getItem('name')); //Veo un Item del localStoragesessionStorage.setItem('name','Bob'); //Agrego un Item al sessionStoragesessionStorage.removeItem('name'); //Elimino un Item del sessionStorage
console.log(sessionStorage.getItem('name')); //Veo un Item del sessionStorage
</script>
Por lo que podemos decir que a diferencia de las cookies, NO contamos con ninguna medida que impida a Javascript acceder al localStorage o al sessionStorage.
Conclusión
Es fundamental conocer las distintas maneras en las cuales una aplicación puede gestionar su autenticación a la hora de realizar un pentest o bug bounty, dado que tener este conocimiento nos permite saber si determinados ataques pueden ser llevados a cabo o no, tales como XSS o CSRF.
Referencias
https://github.com/alex996/presentations/blob/master/auth.md
https://medium.com/@kennch/stateful-and-stateless-authentication-10aa3e3d4986
https://www.youtube.com/watch?v=zR_UkpPZC4M
https://www.youtube.com/watch?v=GihQAC1I39Q
https://www.youtube.com/watch?v=KV_WSVXqUds
https://www.youtube.com/watch?v=KV_WSVXqUds
https://www.youtube.com/watch?v=2PPSXonhIck