Estamos desarrollando una aplicación web móvil donde los usuarios desean (y es un requisito no flexible) estar registrados durante mucho tiempo.
La solución que estamos desarrollando tiene una parte de cliente web en HTML + JS y un middleware en Java. Almacenar las credenciales de los usuarios en el middleware no es una opción porque no queremos tener un solo punto donde algún Administrador pueda obtener TODAS las credenciales de los usuarios. Así que para ser cortos estos son los requisitos:
- Recuérdame por mucho tiempo
- Middleware no puede almacenar las credenciales de los usuarios
- Los sistemas de autenticación en el Backend del middleware no pueden producir un token de sesión de larga duración
- Queremos proteger las credenciales de los usuarios más que el acceso a la aplicación
Sabemos muy bien que almacenar credenciales en HTML LocalStorage o Cookies es una muy mala práctica de seguridad, pero:
1) Los usuarios saben que tienen mucho tiempo de "recordarme" y es su responsabilidad cerrar la sesión (Seguridad frente a Usabilidad)
Obviamente, almacenar las credenciales en texto plano en HTML LocalStorage no es una opción porque el ataque XSS puede robar las credenciales, por lo que hemos diseñado una solución y queremos discutir su seguridad aquí. Un pequeño aviso: nos gustaría discutirlo bajo un punto de vista real, no una visión académica;)
a) los usuarios ponen sus credenciales en un formulario web b) una libreta JS encripta las credenciales con una clave pública RSA (1024) y coloca la carga útil encriptada (EP) en el almacenamiento local c) el EP se envía al middleware que lo descifra con la clave privada y autentica a los usuarios para el (los) sistema (s) backend (puede haber muchos sistemas backend con SSO): hay un ID de sesión para evitar el descifrado en cada llamada (cuando la sesión expira el cliente reenviar el EP) d) si el EP existe en el lado del cliente, el cliente lo envía y autentica nuevamente al usuario e) si el usuario desea cerrar la sesión, el cliente elimina el EP y le entrega el formulario de inicio de sesión
Los puntos de seguridad son:
a) en el lado del cliente solo hay un elemento cifrado con un algoritmo asimétrico == > ninguno puede descifrarlo b) Consideramos que es mucho más difícil para un Administrador colocar dentro del middleware que robar credenciales en el disco c) Cada N meses renovamos las claves RSA y todos los usuarios deben volver a autenticarse
Los únicos ataques que puedo imaginar son:
a) un complemento del navegador que roba las credenciales antes del cifrado == > Esto es cierto para TODAS las formas de autenticación web b) un ataque de repetición: el robo de los permisos de carga útil enc para autenticar suplantando a los usuarios reales == > esto es un problema, pero las credenciales de los usuarios son seguras y esto equilibra el rememberme muy largo (el mismo problema de una sesión muy larga)
No puedo imaginar otro tipo de ataques.
Estoy muy abierto a todas las opiniones para mejorar la seguridad de nuestra solución (pero la facilidad de uso es muy importante ...)