Necesitamos almacenar el JWT en la computadora del cliente. Si lo almacenamos en un LocalStorage / SessionStorage, entonces puede ser fácilmente capturado por un ataque XSS. Si lo almacenamos en cookies, un pirata informático puede usarlo (sin leerlo) en un ataque CSRF y suplantar al usuario y ponerse en contacto con nuestra API y enviar solicitudes para realizar acciones u obtener información en nombre de un usuario.
Pero hay varias formas de asegurar el JWT en las cookies para que no se roben fácilmente (pero todavía hay algunas técnicas avanzadas para robarlas). Pero si desea confiar en LocalStorage / SessionStorage, puede acceder a él mediante un simple ataque XSS.
Entonces, para resolver el problema CSRF, utilizo cookies de envío doble en mi aplicación.
Método de doble envío de cookies
Almacene JWT en una cookie HttpOnly y úsela en modo seguro para transferir a través de HTTPS.
La mayoría de los ataques CSRF tienen un origen o encabezado de referencia diferente con su host original en sus solicitudes. Así que verifique si tiene alguno de ellos en el encabezado, ¿provienen de su dominio o no? Si no, rechazarlos. Si tanto el origen como el referente no están disponibles en la solicitud, no se preocupe. Puede confiar en el resultado de los resultados de validación del encabezado X-XSRF-TOKEN que explico en el siguiente paso.
Si bien el navegador proporcionará automáticamente sus cookies para el dominio de la solicitud, existe una limitación útil: el código JavaScript que se ejecuta en un sitio web no puede leer las cookies de otros sitios web. Podemos aprovechar esto para crear nuestra solución CSRF. Para evitar ataques CSRF, debemos crear una cookie extra legible de Javascript que se llama: XSRF-TOKEN. Esta cookie debe crearse cuando el usuario inicia sesión y debe contener una cadena aleatoria, no adivinable. También guardamos este número en el JWT como un reclamo privado. Cada vez que la aplicación JavaScript desee realizar una solicitud, deberá leer este token y enviarlo en un encabezado HTTP personalizado. Debido a que estas operaciones (leer la cookie, configurar el encabezado) solo se pueden realizar en el mismo dominio de la aplicación JavaScript,
Angular JS te hace la vida más fácil
Afortunadamente, estoy usando Angular JS en nuestra plataforma y paquetes de Angular con el enfoque de token CSRF, lo que simplifica la implementación. Por cada solicitud que nuestra aplicación Angular haga del servidor, el $http
servicio Angular hará estas cosas automáticamente:
- Busque una cookie llamada XSRF-TOKEN en el dominio actual.
- Si se encuentra esa cookie, lee el valor y lo agrega a la solicitud como el encabezado X-XSRF-TOKEN.
Por lo tanto, la implementación del lado del cliente se gestiona automáticamente. Solo necesitamos establecer una cookie nombrada XSRF-TOKEN
en el dominio actual en el lado del servidor y cuando nuestra API recibió alguna llamada del cliente, debe verificar el X-XSRF-TOKEN
encabezado y compararlo con el XSRF-TOKEN
en el JWT. Si coinciden, entonces el usuario es real. De lo contrario, es una solicitud falsificada y puede ignorarla. Este método está inspirado en el método de "Cookie de doble envío".
Precaución
En realidad, aún eres susceptible a XSS, es solo que el atacante no puede robarte el token JWT para su uso posterior, pero aún puede hacer solicitudes en nombre de tus usuarios usando XSS.
Ya sea que almacene su JWT en localStorage
o almacene su token XSRF en una cookie que no sea HttpOnly, XSS puede agarrarlos fácilmente. Incluso su JWT en una cookie HttpOnly puede ser capturado por un ataque XSS avanzado como el método XST .
Por lo tanto, además del método de doble envío de cookies, siempre debe seguir las mejores prácticas contra XSS, incluido el escape de contenido. Esto significa eliminar cualquier código ejecutable que haga que el navegador haga algo que usted no quiere que haga. Por lo general, esto significa eliminar // <![CDATA[
etiquetas y atributos HTML que hacen que se evalúe JavaScript.
Leer más aquí: