ruby-on-rails - tipos - t de cobre
¿El token_authenticatable del dispositivo es seguro? (3)
Estoy compilando una API sencilla con la API de Rails , y quiero asegurarme de que estoy en el camino correcto aquí. Estoy usando el dispositivo para manejar los inicios de sesión, y decidí ir con la opción token_authenticatable
de Devise, que genera una clave API que debes enviar con cada solicitud.
Estoy emparejando la API con una interfaz de red troncal / marioneta y generalmente me pregunto cómo debo manejar las sesiones. Lo primero que pensé fue simplemente almacenar la clave api en un almacenamiento local o una cookie, y recuperarla en la carga de la página, pero algo sobre el almacenamiento de la clave de la API me molestó desde el punto de vista de la seguridad. ¿No sería fácil agarrar la clave api ya sea buscando en el almacenamiento local / la cookie o husmeando cualquier solicitud que se realice, y usarla para suplantar a ese usuario indefinidamente? Actualmente, estoy restableciendo la clave de la API cada vez que inicie sesión, pero incluso eso parece frecuente: cada vez que inicies sesión en cualquier dispositivo, significa que cerrarás sesión en todos los demás, lo cual es un poco molesto. Si pudiera descartar este reinicio, creo que mejoraría desde el punto de vista de la usabilidad.
Puedo estar totalmente equivocado aquí (y espero que lo esté), ¿alguien puede explicar si autenticar de esta manera es confiablemente seguro, y si no, qué buena alternativa sería? En general, estoy buscando una manera de mantener de forma segura a los usuarios ''iniciados'' en el acceso a la API sin tener que forzar la re-autenticación con frecuencia.
De acuerdo con el proyecto README, la gema devise_token_auth se inspiró en esta publicación de : https://github.com/lynndylanhurley/devise_token_auth
Puede intentar usar rails4 con su API, proporciona más seguridad y usa el dispositivo 3.1.0rc
En Rails 4.0, se han extraído varias características en gemas.
- ActiveRecord :: SessionStore
- Almacenamiento en caché de acciones
- Almacenamiento en caché de página
- Muñeca rusa: almacenamiento en caché a través de caducidad basada en claves con administración de dependencia automática de plantillas anidadas.
http://blog.envylabs.com/post/41711428227/rails-4-security-for-session-cookies
Devise 3.1.0.rc se ejecuta en Rails 3.2 y Rails 4.0. http://blog.plataformatec.com.br/2013/08/devise-3-1-now-with-more-secure-defaults/
Devise es la
TokenAuthenticatable
deTokenAuthenticatable
en 3.1.0rc pero puede construir su propio métodoTokenAuthenticatable
para el problema de seguridad. Es más confiable y seguro.
Para token, session store puede ir a http://ruby.railstutorial.org/chapters/sign-in-sign-out y http://blog.bigbinary.com/2013/03/19/cookies-on-rails.html para más comprensible.
Por último, debe pasar por este tipo de cifrado y descifrado " No se pueden descifrar los datos cifrados almacenados " para obtener más seguridad.
token_authenticatable
es vulnerable a los ataques de sincronización, que están muy bien explicados en esta publicación de blog . Estos ataques fueron la razón por la cual token_authenticatable
se eliminó de Devise 3.1. Vea la publicación del blog de plataformatec para más información.
Para tener el mecanismo de autenticación de token más seguro, el token:
Debe ser enviado a través de HTTPS.
Debe ser aleatorio, de fuerza criptográfica.
Debe ser comparada de forma segura.
No debe almacenarse directamente en la base de datos. Solo un hash del token se puede almacenar allí. (Recuerde, token = contraseña. No almacenamos contraseñas en texto sin formato en el db, ¿verdad?)
Debería caducar según alguna lógica.
Si renuncia a algunos de estos puntos en favor de la usabilidad, terminará con un mecanismo que no es tan seguro como podría ser. Es tan simple como eso. Sin embargo, debe estar lo suficientemente seguro si cumple los tres primeros requisitos y restringe el acceso a su base de datos.
Expandiendo y explicando mi respuesta:
Use HTTPS . Este es definitivamente el punto más importante porque se trata de sniffers.
Si no usa HTTPS, muchas cosas pueden salir mal. Por ejemplo:
Para transmitir de forma segura las credenciales del usuario (nombre de usuario / correo electrónico / contraseña), tendría que usar la autenticación resumida, pero eso simplemente no lo hace en estos días, ya que los hash salados pueden ser forzados .
En Rails 3, las cookies solo están cubiertas por la codificación Base64, por lo que pueden revelarse con bastante facilidad. Consulte Decodificación de rieles en las cookies de sesión para obtener más información.
Sin embargo, desde Rails 4, la tienda de cookies se cifra para que los datos se verifiquen digitalmente y sean ilegibles para un atacante. Las cookies deben ser seguras siempre que su
secret_key_base
no se filtre.
Genera tu token con:
-
SecureRandom.hex
solo si estás en Ruby 2.5+. - La gema
sysrandom
si estás en un Ruby más viejo.
Para obtener una explicación de por qué es necesario, sugiero leer el README de
sysrandom
y la publicación de blog Cómo generar números aleatorios seguros en varios lenguajes de programación .-
Encuentra el registro del usuario usando la identificación del usuario, correo electrónico o algún otro atributo. Luego, compare el token de ese usuario con el token de la solicitud con
Devise.secure_compare(user.auth_token, params[:auth_token]
. Si está en Rails 4.2.1+, también puede usarActiveSupport::SecurityUtils.secure_compare
.No encuentre el registro del usuario con un buscador de Rails como
User.find_by(auth_token: params[:auth_token])
. ¡Esto es vulnerable a los ataques de tiempo!Si va a tener varias aplicaciones / sesiones al mismo tiempo por usuario, entonces tiene dos opciones:
Almacene el token no encriptado en la base de datos para que pueda ser compartido entre los dispositivos. Esta es una mala práctica, pero creo que puede hacerlo en nombre de UX (y si confía en sus empleados con acceso a DB).
Almacene tantos tokens cifrados por usuario como desee para permitir las sesiones actuales. Entonces, si desea permitir 2 sesiones en 2 dispositivos diferentes, mantenga 2 hashes de token distintos en la base de datos. Esta opción es un poco menos fácil de implementar, pero definitivamente es más segura. También tiene la ventaja de permitirle a sus usuarios la opción de finalizar sesiones activas actuales en dispositivos específicos mediante la revocación de sus tokens (al igual que GitHub y Facebook).
Debe haber algún tipo de mecanismo que haga que el token expire. Al implementar este mecanismo, tenga en cuenta la compensación entre UX y seguridad.
Google expira un token si no se ha utilizado durante seis meses .
Facebook vence un token si no se ha utilizado durante dos meses :
Las aplicaciones móviles nativas que usan los SDK de Facebook obtendrán tokens de acceso de larga duración, válidos durante aproximadamente 60 días. Estos tokens se actualizarán una vez al día cuando la persona que usa su aplicación realice una solicitud a los servidores de Facebook. Si no se realizan las solicitudes, el token expirará después de aproximadamente 60 días y la persona tendrá que pasar por el flujo de inicio de sesión nuevamente para obtener un nuevo token.
Actualice a Rails 4 para usar su almacenamiento de cookies encriptado. Si no puede, encripte la cookie store usted mismo, como se sugiere here . No habría absolutamente ningún problema al almacenar un token de autenticación en un almacén de cookies cifrado.
También debe tener un plan de contingencia, por ejemplo, una tarea de rake para restablecer un subconjunto de tokens o cada token en la base de datos.
Para comenzar, puede consultar esta idea (de uno de los autores de Devise) sobre cómo implementar la autenticación de tokens con Devise. Finalmente, el Railscast sobre cómo asegurar una API debería ser útil.