¿Puedo evitar un ataque de repetición de mis JWT firmados?

24

He implementado una autenticación sin estado a través de HTTP en Laravel, usando JWTs.

  1. Envié mi nombre de usuario / contraseña desde la interfaz.
  2. El servidor autentica al usuario, devuelve un JWT firmado con un tiempo de caducidad.
    • Estoy usando el algoritmo HS512 para firmar con una clave privada (solo disponible para el servidor).
  3. El frontend almacena el token para futuras solicitudes.
  4. El frontend envía la siguiente solicitud con el token incluido.
  5. El servidor verifica que el token es válido y no está vencido, y permite que la acción continúe en caso afirmativo a ambos.
  6. Cuando el token caduca, el servidor envía un mensaje de "cierre de sesión".

Todas estas comunicaciones se producen a través de HTTPS.

Así que puedo ver que esto es seguro desde estos puntos:

  • Los atacantes no pueden oler el tráfico y robar el token JWT debido a HTTPS.
  • Los atacantes no pueden generar ni enviar ningún token extraño porque el servidor verifica la firma usando su clave privada.
  • Los atacantes no pueden modificar qué usuario (y, por lo tanto, la función + permisos del solicitante) realiza la solicitud, porque eso es parte de la reclamación sub en el token.

Pero tengo dos preguntas :

  1. ¿Qué sucede si hay un virus en la computadora o dispositivo móvil del usuario y se robó un token válido de la memoria RAM o del navegador? Luego puede enviar más solicitudes, y serán aceptadas. ¿Hay alguna forma de protegerse contra esto?
  2. ¿Hay otra forma de atacar este sistema que no estoy viendo?
pregunta Aditya M P 02.08.2014 - 18:13
fuente

3 respuestas

18

El reclamo jti como se describe aquí es un mecanismo opcional para evitar más ataques de repetición. De la especificación:

  

4.1.7. "jti" (JWT ID) Claim

     

La reclamación "jti" (JWT ID) proporciona un identificador único para el JWT.      El valor del identificador DEBE ser asignado de una manera que asegure que      hay una probabilidad insignificante de que el mismo valor sea      asignado accidentalmente a un objeto de datos diferente; si la aplicación      utiliza múltiples emisores, las colisiones DEBEN ser prevenidas entre los valores      Producido por diferentes emisores también. El reclamo "jti" puede ser usado      para evitar que el JWT se reproduzca. El valor "jti" es un caso      cadena sensible El uso de esta reclamación es OPCIONAL.

En última instancia, esto hace que su servidor sea con estado, pero previene contra repeticiones ilimitadas si detecta un comportamiento anómalo, o si un usuario informa una actividad sospechosa. Considere el siguiente escenario.

  1. Un usuario inicia sesión. Su servidor genera un JWT y almacena la firma, así como algunos metadatos (la identificación del usuario y el tipo de cliente que realiza la solicitud, y el jti ).
  2. El usuario informa de comportamiento sospechoso.
  3. La aplicación "cierra la sesión" del usuario de todos los dispositivos mediante la eliminación de todos los JWT en la tienda backend adjunta a ese usuario. Ahora la aplicación puede decir "Sé que tienes una firma válida, pero no la estoy aceptando porque no la creé".
    • Si sus metadatos son lo suficientemente precisos, puede usar jti más información adicional para, por ejemplo, cerrar la sesión del usuario de los dispositivos dados.

Como se mencionó anteriormente, esto inevitablemente hace que su servidor tenga estado. Esto tampoco evita los ataques de repetición, pero puede detener más ataques de este tipo después de que se haya detectado uno.

Un método alternativo / adicional PUEDE prevenir completamente los ataques de repetición hasta cierto punto, a riesgo de inconvenientes potenciales para el usuario. Haga que la dirección IP del usuario forme parte del reclamo Y los metadatos almacenados al iniciar sesión, y valide que la IP que usa el JWT sea la que usted espera. Esto puede ser frustrante para un usuario que, por ejemplo, funciona tanto desde casa como en una cafetería, pero podría ser un requisito aceptable para aplicaciones de alta seguridad.

    
respondido por el bretmattingly 24.11.2015 - 17:34
fuente
4

Si hay código que se ejecuta en el mismo contexto de su aplicación web, ya sea parte de un ataque XSS en el navegador, o algún malware / virus en la máquina de los usuarios, sería difícil (¿imposible?) diferenciarlos peticiones de los tuyos.

Si el atacante tiene acceso a la computadora, también podría robar los datos de las solicitudes normales de las aplicaciones a su servidor.

Potencialmente, podría realizar un análisis de estilo de detección de intrusiones en el lado del servidor: por ejemplo compruebe si hay un alto número de solicitudes o recuentos de artículos; aplique algún esquema de referencia personalizado donde sepa qué componentes de su aplicación web realizan solicitudes de datos. Entonces, ¿tal vez desencadenar una reautenticación cuando detecte un comportamiento anómalo? También necesitaría una forma de servidor para caducar su JWT por encima del exp incrustado en el JWT.

    
respondido por el Kevin Hakanson 25.11.2014 - 15:37
fuente
1

¿Por qué no tener una fecha y hora como carga útil y caducidad? No es necesario cambiar la carga útil y la lógica de la aplicación puede caducar el token. O use un nuevo secreto basado en la naturaleza de una hoja (similar a DUKPT ), por lo que una nueva solicitud de token invalida la anterior.

    
respondido por el TheBB 30.08.2018 - 15:48
fuente

Lea otras preguntas en las etiquetas