Tengo un backend API REST que tiene HTTPS (y HTTP bloqueado) y uso JWT como mecanismo de autenticación. El lado del cliente es la aplicación iOS / Android. Quiero agregar una capa de protección en la API crítica mediante el uso del cliente para prevenir (en su mayoría) la reenvío (llamar involuntariamente a la misma API dos veces debido a una mala red / IU) y (tal vez) un ataque de repetición. Los detalles actuales son los siguientes.
(Todas las llamadas REST son a través de HTTPS)
- el cliente realiza una llamada a la API utilizando el nombre de usuario y la contraseña para intercambiar un JWT desde el lado del servidor
- el cliente usa el JWT obtenido (encabezado HTTP) y realiza una subsecuente llamada de API al servidor
- servidor backend, compruebe el JWT y ejecute la solicitud
El problema actual es que cualquier persona que pueda interceptar el paquete HTTP puede reproducir la llamada a la API. Además, en una situación de mala red, el cliente puede presionar el botón enviar / confirmar dos veces y volver a enviar la solicitud.
Lo que propongo es lo siguiente:
- el cliente realiza una llamada a la API utilizando el nombre de usuario y la contraseña para intercambiar un JWT desde el lado del servidor
- el cliente usa el JWT obtenido + un nonce generado por el cliente y realiza una llamada de API subsecuente al servidor backend.
- el servidor backend comprueba primero el JWT y luego el nonce. Supongamos que tenemos una tienda de k-v con TTL como Redis.
- Si el nonuce existe en Redis, rechazamos la solicitud. De lo contrario, aceptamos la solicitud y configuramos el nonuce en Redis con un TTL predefinido (por ejemplo, ¿1hr?) Para que se rechace una repetición.
Tengo que admitir que tengo muy poco conocimiento sobre seguridad. ¿Quiero saber si esta propuesta es legítima? ¿O me falta algo importante? Si mi idea está bien, ¿cuál es el mejor algoritmo para generar el nonce? ¿Es necesario que el lado del servidor "decodifique" el nonce para ver si se ajusta al protocolo antes de compararlo con Redis?