3

I am creating an ember app that has devise worked in for authentication. I'm really getting stuck with how all these different tokens come into play.

I'm reimplementing the recently deprecated :token_authenticatable devise "strategy" using the method described here. I'd like to add token authentication to my API and sign requests to that with the user's token.

What I'm wondering is, even though it's using Devise.secure_compare to thwart timing attacks, it's still storing the authentication_token in plain text, so if anyone were to gain access to the database, those tokens could potentially used to steal a session, no?

Devise seems to use two different types of "tokens" in the modules:

  1. Creating a token with Devise.friendly_token and storing it as plain text. Then doing a look up by this token (as used in :rememberable).
  2. Creating a salted token with Devise.token_generator (as seem in :confirmable).

The second method looks to me like the token is salted using Devise.secret_key which is derived from the Rails secret in config/secrets.yml. That way the token is encrypted and if the database was exposed for some reason, the tokens couldn't be used, right? Would be the equivalent of having a private key (rails secret) and a public key (authentication_token).

I have quite a few concerns:

  • Should I use Devise.token_generator to create my authentication_tokens?
  • What is the word on security for these type of tokens?
  • How does the CSRF token factor into Devise?
typeoneerror
  • 55,990
  • 32
  • 132
  • 223

1 Answers1

3

Devise does a lot of things, and not necessarily the things your particular application needs or in the way your applications needs. I found it wasn't a good fit for my application. The lack of support/removal of api token authentication provided enough motivation to move on and implement what I needed. I was able to implement token auth from scratch fairly easily. I also gained full flexibility for managing user signup/workflows/invitations and so on without the constraints and contortions required of Devise. I still use Warden which Devise also uses for its Rack middleware integration.

I've provided an example of implementing token authentication/authorisation on another stackoverflow question. You should be able to use that code as a starting point for your token authentication, and implement any additional token protection you require. I'm also using my oAuth token approach with Ember.js.

Also consider if encrypting tokens is just hand-waving because depending on your deployment environment and how you manage your master key/secret, it may be giving a false sense of security. Also remember that encryption says NOTHING about the integrity/validity of the token or related authentication/authorisation information, unless you also have a MAC/signature that encompasses everything used in your access decision. So whilst you may go to the trouble of protecting tokens from attackers whom have access to your database, it may be trivial for those same attackers to inject bogus tokens or elevate privileges for existing users in your database, or just steal or modify the real data which may be what they really want to achieve!

I've made some large comments in respect of providing integrity and confidentiality controls for ALL authentication/authorisation information (which tokens are part of) on the Doorkeeper gem. I would suggest reading the full issue to get an idea of the scope of the problem and things to consider because none of the gems currently do what should be done. I've provided an overview on how to avoid storing tokens on the server altogether and I've provided some sample token generation and authentication code in a gist which also deals with timing based attacks.

Community
  • 1
  • 1
Andrew Hacking
  • 6,296
  • 31
  • 37