Estoy construyendo SPA (React / Redux) y requiero la autenticación del usuario. He encontrado discusiones similares, pero no he encontrado respuestas para las preguntas que describo a continuación. Aquí hay algunas opciones que encontré para implementar:
Opción 1: mantener JWT en localStorage
Ataque CSRF : no es vulnerable, ya que no se utilizan cookies.
Ataque XSS : Vulnerable. Cualquier código JS en el front-end podrá robar el token y enviarlo al atacante. Con Content-Security-Policy habilitado, atacado no puede robarse / enviarse a sí mismo jwt, pero aún así puede realizar la solicitud directamente desde el navegador del cliente.
Opción 2: mantener JWT en la cookie ( secure
y http-only
)
Ataque CSRF : Vulnerable. El cliente puede seguir el sitio web malintencionado, lo que hará que la solicitud, la cookie adjunta y la solicitud sean exitosas
Ataque XSS : Vulnerable. JS no puede leer las cookies, pero a través de JS el atacante solo puede realizar solicitudes de back-end válido, las cookies se adjuntan automáticamente y todas las solicitudes se realizarán correctamente.
Opción 3: mantener JWT (con xsrf_token configurado) en cookie + mantener xsrf_token en localStorage / JS-legible cookie
La solución se basa en this y es similar a Método de envío doble de cookies
Ataque CSRF : No es vulnerable. Si el cliente sigue un sitio web malintencionado, que realiza una solicitud astuta, esa solicitud se descartará, ya que xsrf_token no se pasó del navegador del cliente junto con la cookie. Y, dado que la cookie no es visible para el atacante (viene directamente del navegador del cliente), no puede crear un xsrf_token falso para adjuntar con la solicitud.
Ataque XSS : Vulnerable. Los atacantes JS pueden leer xsrf_token en localStorage / JS-cookie legible. Por lo tanto, un atacante podrá realizar una solicitud maliciosa directamente desde su JS inyectado desde el navegador del cliente.
Originalmente, quería usar la opción 1. Pero me preocupaba XSS, así que comencé a buscar alternativas. Este artículo y el número de otros desaconseja el almacenamiento local, y recomienda el uso de la protección CSRF de Cookie +.
La opción 3 parece ser la solución popular, a partir de los datos recopilados, pero aún tiene XSS, al igual que la opción 1: JS inyectado puede realizar solicitudes maliciosas directamente desde el navegador del cliente. El único beneficio es que, en la opción 1, el usuario / atacante puede leer los datos codificados en JWT, mientras que en la opción 3 no lo está (como se almacena en una cookie). pregunta relacionada
Q1. ¿Hay otros beneficios de la Opción 3 sobre la Opción 1?
Q2. Si opto por la opción 3, ¿estoy introduciendo algunos otros vectores de ataque que aún no he considerado?
Q3. ¿Hay alguna otra forma de mitigación de CSRF, en lugar de mantener el estado en el front-end (localStorage / sessionStorage / Redux store / JS-legible cookie) que siempre es vulnerable a XSS?
Sé que no hay una bala mágica en seguridad. ¿Pero quizás hay otros enfoques / opciones para este problema? Para eliminar XSS, debe ir al modo de cookie completo. Pero para ir solo a las cookies, debe tener xsrf_token de todos modos en el front-end del usuario (localStorage / sessionStorage / Redux store / JS-legible cookie), que es vulnerable a XSS. Esto parece ser un problema catch-22.