Using rails secret to salt authentication keys in devise - ruby-on-rails

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:
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).
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?

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.

Related

Rails Devise token and cookie session at same time

I have a rails web which has been using cookie session authentication (devise) from its beginning. Now, we are developing an ionic mobile application which uses the API available from the rails application.
I have considered to use JWT or token authentication for this new application but I can't find a way to combine both authentication methods, cookie and JWT. Also, both applications have different requirements. For example, in the web a user can have concurrent sessions only if he/she has a certain role. On the opposite, in the mobile application it is possible to have concurrent session without any restriction.
I have reading a lot trying to figure how to combine both methods but I can't find the way. Maybe I should consider to use only one of the methods (JWT) or use another approach (doorkeeper).
Finally I have found a solution. According to refaelos and Zac Stewart, I have combined devise with JWT gem, using the last as a new strategy for the first. By this way, when I don't use JWT tokens, devise will choose the default strategy (database_authenticatable in my case). Otherwise, it will use JWT strategy.
However, when the user is not authenticated and make a post request to Session#create to get the credentials, the strategy chosen by devise/warden is database_authenticatable. In order to avoid this, I needed to add a new parameter to the request but only for this case because, as I said, when the token appears in the request, the new strategy is selected.
See also:
An Introduction to Using JWT Authentication in Rails

How to secure basic methods like user creation in an API

I'm learning about developing APIs with rails, but I can't find how to secure the base methods like user creation. Let's say I have a rails backend API and a frontend mobile app. I want the app to be able to make API calls to create a new user. Off course, not everyone should be able to create a new user, so it should have some kind of authentication. I could use basic or digest authentication (doesn't really matter, because I'll definitely use SSL), but then I would have to hardcode the credentials into my app. If the credentials are discovered somehow, I would have to change them, but that would mean that all instances of the app are no longer authenticated and they can't create users anymore.
The things I would like to have:
Only my apps should be able to use the user creation calls.
It should be easy to change the credentials, or the credentials should change automatically over time. If they would involve the date and time for example, it would be harder to crack.
It should be impossible (or VERY hard) to beat the system behind it, while having knowledge of a couple of the credentials over time.
Would it be possible for example to let my apps generate public and private key pairs at random and use them? What's the standard way of securing these calls?
Thanks in advance,
Rugen Heidbuchel
I could share my own experience:
https protocol communication with API. That is your last sentence about private/public keys, all is built in into https.
Doorkeeper (we combine it with Devise) gem for Oauth (github accounts in my case) as authentication, while you can use pairs of user/passwords instead.
CanCanCan gem as authorization (User creation restriction is about authorization and not authentication)
Set of that three tools should provide essential security level for your API. I believe cancancan could be under discussion, while devise is mostly industry standard.

OAuth: what information should I store in tokens

I am creating an OAuth server which issues tokens to users. However, I don't want to store tokens in the database, and I want the processing to be fast.
What I'm thinking is to include various information in the token, so that when I decrypt it, the information is already enough to check for permissions and scopes.
I'm a little worried about the token's length growing as I add more scopes.
Is this a good idea? If not, what can you recommend?
What you are talking here is about InMemoryTokenStore which is the default implementation. Also Oauth2 already maintains the information required to check permissions and scopes in token in form of different access roles provided by authorization server to various clients. I think you don't need to explicitly store anything in token.

Rails: token authentication from scratch

I've got a rails app I want to start enabling some iOS integration with. I have a basic authentication system built mostly from scratch with a little help from Sorcery.
My understanding is there's basically two options for mobile integration: HTTP Basic Auth or Token Auth. From what I've been able to find so far it looks like Token Authentication is the preferred method.
I am not familiar with what token authentication is or how it is supposed to work, and I have not really been able to find any decent guides on this, except for a few tutorials on how to use the relevant module in the Devise library.
So, my question is, what is the basic theory of Token Authentication, and what would a from-scratch token auth system in rails look like? I understand that sharing the code for the entire system might be overkill for an SO answer, but I would be very grateful if anyone can help me understand a basic schematic of how such a system is supposed to work. I'd also happily accept links to any good existing materials on how to do this from scratch, as the main problem is I haven't been able to find anything like that.
Thanks!
Devise and Authlogic have a nice Token Authentication solution. You can either use one of these gems or to implement your own check their source code for inspiration.
Below is my understanding of how token authentication works:
The user signs in using a username/password combination through a
post request.
You authenticate the user and generate a unique token and
store it in the db.
You send this token back to the iOS device.
The device stores this token in memory.
Any subsequent call to the api need this token passed in as an
additional param to auth the user.
For this process to be secure this token needs to have an expiration
date and the communication between the iOS device and the server
must be encrypted through SSL.
For convenience you can store the user credentials on the device
using the iOS keychain.
I hope this helps.
I think there are three difficulties here.
There are very few books focused on authentication technique
The key word "token authentication" is confusing to use in security/authentication field.
Rails related documentation tend to be "how to."
So, Googling won't reveal good resources for this purpose. I know this field well, but it's difficult, especially due to reason 2.
In my understanding, "token" here work as an authenticated identity in the system, and provide bridge between authentication system and authorization system. But to understand this, you must understand overall system.
Let me provide few pointer with regard to authentication technique books and some papers here.
Butler Lampson did many work related authentication, and some of the articles are very good material to understand authentication/authorization framework. that might be helpful. One of the example is Computer security in the real world(2004).
Book written for Public Key Infrastructure(PKI) might be helpful. there are several of such. Such as Understanding PKI: Concepts, Standards, and Deployment Considerations, 2nd edition
Hope this helps.
ember-auth has a nice tutorial for token authentication for rails with devise and ember. However, it could also be applied to sorcery or to a custom authentication system. I think this is the best approach to authentication for an ember.js App.
https://github.com/heartsentwined/ember-auth-rails-demo

Looking for suggestions for building a secure REST API within Ruby on Rails

I'm getting started on building a REST API for a project I'm working on, and it led me to do a little research as to the best way to build an API using RoR. I find out pretty quickly that by default, models are open to the world and can be called via URL by simply putting a ".xml" at the end of the URL and passing appropriate parameters.
So then the next question came. How do I secure my app to prevent unauthorized changes? In doing some research I found a couple articles talking about attr_accessible and attr_protected and how they can be used. The particular URL I found talking about these was posted back in May of '07 (here).
As with all things ruby, I'm sure that things have evolved since then. So my question is, is this still the best way to secure a REST API within RoR?
If not what do you suggest in either a "new project" or an "existing project"scenario?
There are several schemes for authenticating API requests, and they're different than normal authentication provided by plugins like restful_authentication or acts_as_authenticated. Most importantly, clients will not be maintaining sessions, so there's no concept of a login.
HTTP Authentication
You can use basic HTTP authentication. For this, API clients will use a regular username and password and just put it in the URL like so:
http://myusername:mypass#www.someapp.com/
I believe that restful_authentication supports this out of the box, so you can ignore whether or not someone is using your app via the API or via a browser.
One downside here is that you're asking users to put their username and password in the clear in every request. By doing it over SSL, you can make this safe.
I don't think I've ever actually seen an API that uses this, though. It seems like a decently good idea to me, especially since it's supported out of the box by the current authentication schemes, so I don't know what the problem is.
API Key
Another easy way to enable API authentication is to use API keys. It's essentially a username for a remote service. When someone signs up to use your API, you give them an API key. This needs to be passed with each request.
One downside here is that if anyone gets someone else's API key, they can make requests as that user. I think that by making all your API requests use HTTPS (SSL), you can offset this risk somewhat.
Another downside is that users use the same authentication credentials (the API key) everywhere they go. If they want to revoke access to an API client their only option is to change their API key, which will disable all other clients as well. This can be mitigated by allowing users to generate multiple API keys.
API Key + Secret Key signing
Deprecated(sort of) - see OAuth below
Significantly more complex is signing the request with a secret key. This is what Amazon Web Services (S3, EC2, and such do). Essentially, you give the user 2 keys: their API key (ie. username) and their secret key (ie. password). The API key is transmitted with each request, but the secret key is not. Instead, it is used to sign each request, usually by adding another parameter.
IIRC, Amazon accomplishes this by taking all the parameters to the request, and ordering them by parameter name. Then, this string is hashed, using the user's secret key as the hash key. This new value is appended as a new parameter to the request prior to being sent. On Amazon's side, they do the same thing. They take all parameters (except the signature), order them, and hash using the secret key. If this matches the signature, they know the request is legitimate.
The downside here is complexity. Getting this scheme to work correctly is a pain, both for the API developer and the clients. Expect lots of support calls and angry emails from client developers who can't get things to work.
OAuth
To combat some of the complexity issues with key + secret signing, a standard has emerged called OAuth. At the core OAuth is a flavor of key + secret signing, but much of it is standardized and has been included into libraries for many languages.
In general, it's much easier on both the API producer and consumer to use OAuth rather than creating your own key/signature system.
OAuth also inherently segments access, providing different access credentials for each API consumer. This allows users to selectively revoke access without affecting their other consuming applications.
Specifically for Ruby, there is an OAuth gem that provides support out of the box for both producers and consumers of OAuth. I have used this gem to build an API and also to consume OAuth APIs and was very impressed. If you think your application needs OAuth (as opposed to the simpler API key scheme), then I can easily recommend using the OAuth gem.
How do I secure my app to prevent
unauthorized changes?
attr_accessible and attr_protected are both useful for controlling the ability to perform mass-assignments on an ActiveRecord model. You definitely want to use attr_protected to prevent form injection attacks; see Use attr_protected or we will hack you.
Also, in order to prevent anyone from being able to access the controllers in your Rails app, you're almost certainly going to need some kind of user authentication system and put a before_filter in your controllers to ensure that you have an authorized user making the request before you allow the requested controller action to execute.
See the Ruby on Rails Security Guide (part of the Rails Documentation Project) for tons more helpful info.
I'm facing similar questions as you at the moment because i'm also building out a REST api for a rails application.
I suggest making sure that only attributes that can be user edited are marked with attr_accessible. This will set up a white list of attributes that can be assigned using update_attributes.
What I do is something like this:
class Model < ActiveRecord::Base
attr_accessible nil
end
All my models inherit from that, so that they are forced to define attr_accessible for any fields they want to make mass assignable. Personally, I wish there was a way to enable this behaviour by default (there might be, and I don't know about it).
Just so you know someone can mass assign a property not only using the REST api but also using a regular form post.
Another approach that saves building a lot of the stuff yourself is to use something like http://www.3scale.net/ which handles keys, tokens, quotas etc. for individual developers. It also does analytics and creates a developer portal.
There's a ruby/rails plugin ruby API plugin which will apply to policies to traffic as it arrives - you can use it in conjunction with the oAuth gem. You can also us it by dropping varnish in front of the app and using the varnish lib mod: Varnish API Module.

Resources