autenticación de API REST con protección JWT y CSRF para SPA

8

Estoy desarrollando un SPA con back-end REST y quiero tener una autenticación simple basada en token. El objetivo para el respaldo de REST es ser apátrida. Explicaré el modelo de seguridad e intentaré hacer referencia a todas las fuentes para las decisiones que se tomaron durante el diseño. Querría un comentario sobre toda la configuración y responder a algunas preguntas específicas.

Abstract

La autenticación se realizará en un punto final dedicado (por ejemplo / auth / login). La información de inicio de sesión se pasará como un objeto JSON. La información contendrá nombre de usuario y contraseña. Al iniciar sesión correctamente, se emitirá un token JWT firmado. Este token se utilizará para el acceso posterior a la API REST.

La aplicación usará HTTPS y yo controlo todos los subdominios.

Especificaciones

JWT

  • Contiene nombre de usuario, emitido a la hora de vencimiento
  • Contiene notificaciones sobre la pertenencia a roles dentro de una aplicación
  • Contiene un token CSRF (generado aleatoriamente desde un generador pseudoaleatorio criptográficamente seguro)
  • Firmado con una clave HMAC (SHA256) solo disponible para el servidor

Expiración

Se emitirá un token con un breve tiempo de caducidad (por ejemplo, 30 minutos). Se emitirá un token actualizado con cada nuevo vencimiento en cada solicitud (vencimiento de ventana deslizante) con una fecha límite de algo razonable (por ejemplo, 8 horas). El flujo del proceso será el siguiente:

  1. La solicitud de inicio de sesión inicial emitirá un token con una caducidad de 30 minutos
  2. La siguiente solicitud verificará si el token ha caducado. Si está vencido, se bloqueará el acceso. Si no, se cumplirá una solicitud. Se realizará una comprobación en ese momento sobre la edad del token.

    • Si la edad está dentro de la fecha límite (menos de 8 horas), se generará un token actualizado que contiene un nuevo tiempo de caducidad por otros 30 minutos. Emitido en el momento seguirá siendo el mismo que en el token original.
    • Si la antigüedad del token es la fecha límite de aprobación, no se generarán tokens actualizados y el usuario deberá iniciar sesión nuevamente.

Justificación: quiero proteger un token con un breve tiempo de caducidad en caso de que esté comprometido. Tampoco quiero forzar al usuario a volver a iniciar sesión a menudo. Un atacante tendría que solicitar un token nuevo en un período de tiempo inferior al tiempo de caducidad de un token. En caso de que un atacante logre hacer eso, la cantidad máxima de tiempo que él / ella puede usar el token está definida por la fecha límite. El usuario puede permanecer en línea durante un período de tiempo límite establecido. Para una solicitud de negocio, un plazo de 8 horas o un día es suficiente. ¿Es esta implementación lo suficientemente segura? ¿Cuáles son los posibles inconvenientes y vulnerabilidades?

Transporte y almacenamiento JWT

JWT se transportará como una cookie httpOnly al cliente y se almacenará en el repositorio de Cookies en el navegador.

Justificación: para proteger un token del ataque XSS que podría comprometer el token si se mantiene dentro de localStorage / sessionStorage. Esto es por una recomendación de este artículo . ¿Hay algún problema con este enfoque que no sea abrir la implementación a un ataque CSRF?

Protección CSRF

El almacenamiento de tokens JWT dentro de las cookies abrirá la implementación a un ataque CSRF. Para mitigar este problema, se implementa un método de envío doble de cookies. El token CSRF se genera e incluye dentro del token JWT. Este token también se suministra a la aplicación cliente en un objeto JSON de una respuesta a la solicitud de inicio de sesión. La aplicación almacenará CSRF en localStorage y lo enviará con cada solicitud dentro de un encabezado personalizado.

Justificación: según una respuesta a esta referencia a una pregunta this paper , para una protección CSRF efectiva es necesario para vincular criptográficamente el token CSRF con una cookie de identificación / autenticación de sesión. Si incluyo un token dentro de un JWT, ¿se considera que está vinculado criptográficamente a una sesión de seguridad?

Conceptualmente, ¿ve algo incorrecto en esta implementación?

    
pregunta Marko Vodopija 21.02.2017 - 13:10
fuente

1 respuesta

3
  

¿Es esta implementación lo suficientemente segura? ¿Cuáles son los posibles inconvenientes y   vulnerabilidades?

Los JWT son tokens de portador autodescriptivos. Los dos principales inconvenientes de JWT son los tokens obsoletos y la incapacidad de vencerlos a pedido.

Tokens obsoletos

Si el rol de su usuario cambia, no se reflejará en el token emitido. Tendrá que emitir uno nuevo. Lo ideal sería que vencieras al anterior, lo que nos lleva al siguiente problema.

Sin caducidad a petición

Los JWT no pueden caducar a petición, ya que ellos mismos no tienen estado. Un enfoque para resolver esto es la lista negra de JWT, pero eso eliminará la apatridia de su servidor. Esto también significa que su usuario esencialmente no puede cerrar sesión en su aplicación ya que no puede invalidar los tokens a pedido.

Sobre los tokens de vida corta. Si el atacante está en posesión de un token de corta duración, solo puede consultar su API para "mantenerlo vivo" durante el tiempo que lo permita (8 horas o 1 día).

Deberá decidir si esto es lo suficientemente seguro. Todo depende de las compensaciones que estés dispuesto a hacer.

  

Cualquier problema con este enfoque, aparte de abrir el   implementación en un ataque CSRF?

Esto funciona perfectamente. He visto muchos sitios web usarlo. Aunque tienes que preocuparte por CSRF. A menos que su API sea solo JSON. Consulte aquí .

  

Si incluyo un token dentro de un JWT, ¿se considera criptográficamente?   ¿Atado a una sesión de seguridad?

Sí, aunque no puede rotar este secreto de manera efectiva debido a los problemas de terminación bajo demanda que describí anteriormente. Esto es, una vez más, una compensación.

  

Conceptualmente, ¿ve algo incorrecto en esta implementación?

Yo, creo que lo que describiste es perfectamente razonable. Tiene sus inconvenientes y compensaciones, pero solo usted conoce el caso comercial exacto que necesita respaldar. Si no se aceptan el cierre de sesión, los tokens obsoletos y un token CSRF fijo por sesión, todo está bien.

    
respondido por el Daniel Szpisjak 31.07.2017 - 22:50
fuente

Lea otras preguntas en las etiquetas