Dónde almacenar JWT en el navegador? ¿Cómo protegerse contra CSRF?

Sé la autenticación basada en cookies. Los indicadores SSL y HttpOnly se pueden aplicar para proteger la autenticación basada en cookies de MITM y XSS. Sin embargo, se necesitarán más medidas especiales para su aplicación a fin de protegerlo de CSRF. Son un poco complicados. ( referencia )

Recientemente, descubrí que JSON Web Token (JWT) es bastante caliente como una solución para la autenticación. Conozco las cosas sobre encoding, deencoding y verificación de JWT. Sin embargo, no entiendo por qué algunos sitios web / tutoriales dicen que no necesitan protección CSRF si se usa JWT. He leído bastante y trato de resumir los problemas a continuación. Solo quiero que alguien pueda dar una idea general de JWT y aclarar los conceptos que entendí mal sobre JWT.

  1. Si el JWT se almacena en una cookie, creo que es lo mismo que la autenticación basada en cookies, excepto que el servidor no necesita tener sesiones para verificar la cookie / token. Todavía existe riesgo de CSRF si no se implementa una medida especial. ¿JWT no está almacenado en una cookie?

  2. Si el JWT se almacena en localStorage / sessionStorage, entonces no hay cookies, por lo que no es necesario proteger contra CRSF. La pregunta es cómo enviar el JWT al servidor. Encontré aquí sugiere usar jQuery para enviar el JWT por el encabezado HTTP de las solicitudes ajax. Entonces, ¿solo las solicitudes ajax pueden hacer la autenticación?

  3. Además, encontré un blog más muestra para usar “encabezado de autorización” y “portador” para enviar el JWT. No entiendo el método del que habla el blog. ¿Podría alguien explicar más sobre “Encabezado de autorización” y “Portador”? ¿Esto hace que el JWT transmitido por el encabezado HTTP de TODAS las solicitudes? En caso afirmativo, ¿qué hay de CSRF?

Los tokens JWT son populares, ya que se utilizan como el formato de token predeterminado en los nuevos protocolos de autorización y autenticación como OAuth 2.0 y OpenID Connect .

Cuando el token se almacena en una cookie, el navegador lo envía automáticamente junto con cada solicitud al mismo dominio y esto aún es vulnerable a los ataques CSRF.

La autenticación de portador es uno de los esquemas de autenticación definidos en HTTP. Básicamente, significa que YOU pega el token (JWT) en el encabezado HTTP de autorización de una solicitud. El navegador NOT hará esto automáticamente, por lo que no es adecuado para proteger su sitio web. Como el navegador no agrega automáticamente el encabezado a su solicitud, no es vulnerable a un ataque CSRF, que depende de que su información de autenticación se envíe automáticamente al dominio original.

El esquema de portador se usa a menudo para proteger las API web (servicios REST) ​​que se consumen a través de llamadas AJAX o de clientes móviles.

Necesitamos almacenar el JWT en la computadora del cliente. Si almacenamos en LocalStorage / SessionStorage, puede ser capturado fácilmente por un ataque XSS. Si almacenamos en cookies, un pirata informático puede usarlo (sin leerlo) en un ataque CSRF e imitar al usuario, contactar a nuestra API y enviar solicitudes para realizar acciones u obtener información en nombre de un usuario.

Pero hay varias formas de proteger el JWT en cookies para que no se lo roben fácilmente (pero todavía hay algunas técnicas avanzadas para robarlas). Pero si quiere confiar en LocalStorage / SessionStorage, se puede acceder mediante un simple ataque XSS.

Entonces, para resolver el problema de CSRF, utilizo cookies de envío doble en mi aplicación.

Doble método de envío de cookies

  1. Almacene JWT en una cookie HttpOnly y utilícela en modo seguro para transferir a través de HTTPS.

  2. La mayoría de los ataques CSRF tienen un origen diferente o encabezado de referencia con su host original en sus solicitudes. Entonces, verifique si tiene alguno de ellos en el encabezado, ¡vienen de su dominio o no! Si no los rechazas. Si tanto el origen como el referente no están disponibles en la solicitud, entonces no hay problema. Puede confiar en el resultado de los resultados de validación de encabezado X-XSRF-TOKEN que explico en el siguiente paso.

  3. 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 prevenir ataques CSRF, debemos crear una cookie extra legible por Javascript que se llame: XSRF-TOKEN. Esta cookie debe crearse cuando el usuario está conectado y debe contener una cadena aleatoria e indescifrable. También guardamos este número en el propio 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, podemos saber que esto lo está haciendo un usuario real que está usando nuestra aplicación JavaScript.

Angular JS te hace la vida más fácil

Afortunadamente, estoy usando Angular JS en nuestra plataforma y Angular empaqueta el enfoque de token CSRF, lo que nos simplifica la implementación. Por cada solicitud que nuestra aplicación angular haga del servidor, el servicio Angular $http 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 encabezado X-XSRF-TOKEN.

Por lo tanto, la implementación del lado del cliente se maneja por usted, ¡automáticamente! Solo debemos establecer una cookie llamada XSRF-TOKEN en el dominio actual en el lado del servidor y cuando nuestra API recibió una llamada del cliente, debe verificar el encabezado X-XSRF-TOKEN 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 “Enviar doble cookie”.

Precaución

En realidad, aún eres susceptible a XSS, es solo que el atacante no puede robar tu token JWT para usarlo más tarde, pero aún puede realizar solicitudes en nombre de tus usuarios usando XSS.

Ya sea que almacene su JWT en localStorage o almacene su XSRF-token en una cookie que no sea HttpOnly, ambas cosas pueden ser tomadas fácilmente por XSS. 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, incluidos los contenidos de escape. Esto significa eliminar cualquier código ejecutable que haga que el navegador haga algo que usted no quiere. Por lo general, esto significa eliminar // < ![CDATA[ tags // < ![CDATA[ Y los atributos de HTML que causan la evaluación de JavaScript.

Leer más aquí:

  • XSRF de Angular: cómo funciona
  • Dónde almacenar sus JWT: cookies vs almacenamiento web HTML5