Rails security concerns with Authorization token in header for API - ruby-on-rails

I'm building an API and I want every request to contain a token. I found a pretty simple way to do this, but I am wondering if I'm missing any security implications.
The way I'm currently doing it is using authenticate_or_request_with_http_token. I use that to check the token within the header combined with the user's email within a request. If both are legitimate -- then go through with the request.
I am also enforcing https on every request. Is this enough for a secure app? If somebody intercepts the request they can just take the params and the headers and make requests on behalf of a user, but I figured that ssl should encode everything properly. Am I completely misunderstanding ssl as well as the rest of the way I built it?

I think you are basically right.
But the most secure way to do API auth is with something like hmac, where the token is actually generated specific to the specific request and the time, so even if someone does see the URL, they still can't even use it to replay the same API request, let alone make other requests.
http://rc3.org/2011/12/02/using-hmac-to-authenticate-web-service-requests/
For instance, Amazon uses an HMAC-based approach to their API's.
But I think your analysis is correct that in general, if you enforce https, nobody ought to be able to see the pass token clients include in the request. I can't explain why people use HMAC instead; maybe just because there are so so many things that can go wrong and lead to someone seeing the token even in request headers. Including several kinds of man-in-the-middle attacks which ought not to be possible, but if a slip-up somewhere else makes one possible, the HMAC-based approach will still, for instance, prevent a man-in-the-middle from modifying the request the client meant to send, before it reaches the server.
There is HMAC built into the ruby stdlib. Digest::HMAC in the stdlib tells you to use OpenSSL::HMAC instead, but OpenSSL::HMAC contains no docs at all, and Digest::HMAC at least includes some bare bones examples docs. It would be nice to have better docs, but together with the overview of HMAC linked above, you can probably figure out how to use the stdlib ruby hmac to implement your auth pretty easily. It does put a higher burden on the client though, to find an HMAC library in the language of their choice, and implement the hmac auth to your app's specifications (there are a couple choices in how you might incorporate hmac into actual auth flow).

Related

Why do I need to follow the OAuth spec/guidelines?

I feel silly even asking this question, but am at the limits of my understanding, and am hoping someone can provide some context.
I'm looking at the following (https://stormpath.com/blog/token-auth-for-java/) which states:
The access_token is what will be used by the browser in subsequent requests... The Authorization header is a standard header. No custom headers are required to use OAuth2. Rather than the type being Basic, in this case the type is Bearer. The access token is included directly after the Bearer keyword.
I'm in the process of building a website, for which I'll be coding both the back-end REST service, as well as the front-end browser client. Given this context, why do I need to follow any of the guidelines given above? Instead of using the access_token, Authorization and Bearer keywords, what's stopping me from using any keywords I like, or skipping the Bearer keyword entirely in the header? After all, as long as the front-end and back-end services both read/write the data in a consistent manner, shouldn't everything work fine?
Are the keywords and guidelines given above merely best-practice suggestions, to help others better understand your code/service? Are they analogous to coding-styles? Or is there any functional impact in not following the above guidelines?
Given this context, why do I need to follow any of the guidelines given above?
Because they are standardized specifications that everyone is meant to conform to if they want to interact with each other.
Instead of using the access_token, Authorization and Bearer keywords, what's stopping me from using any keywords I like, or skipping the Bearer keyword entirely in the header?
Nothing, except that it won't be OAuth anymore. It will be something custom that you created for yourself that noone else will understand how to use, unless you publish your own spec for it.
After all, as long as the front-end and back-end services both read/write the data in a consistent manner, shouldn't everything work fine?
Who is to say that you alone will ever write the only front-end? Or that the back-end will never move to another platform? Don't limit yourself to making something custom when there are open standards for this kind of stuff.
Are the keywords and guidelines given above merely best-practice suggestions, to help others better understand your code/service?
No. They are required protocol elements that help the client and server talk to each other in a standardized manner.
Authorization is a standard HTTP header used for authentication. It has a type so the client can specify what kind of authentication scheme it is using (Basic vs NTLM vs Bearer, etc). It is important for the client to specify the correct scheme being used, and for the server to handle only the schemes it recognizes.
Bearer is the type of authentication that OAuth uses in the Authorization header. access_token is a parameter of OAuth's Bearer authentication.
If you use the Authorization header (which you should), you must specify a type, as required by RFCs 2616 and 2617:
Authorization = "Authorization" ":" credentials
credentials = auth-scheme #auth-param
auth-scheme = token
auth-param = token "=" ( token | quoted-string )
So, in this case, Bearer is the auth-scheme and access_token is an auth-param.
Are they analogous to coding-styles?
No.
Or is there any functional impact in not following the above guidelines?
Yes. A client using your custom authentication system will not be able to authenticate on any server that follows the established specifications. Your server will not be able to authenticate any client that does not use your custom authentication system.

How should I secure my SPA and Web.API?

I have to implement a web site (MVC4/Single Page Application + knockout + Web.API) and I've been reading tons of articles and forums but I still can't figure out about some points in security/authentication and the way to go forward when securing the login page and the Web.API.
The site will run totally under SSL. Once the user logs on the first time, he/she will get an email with a link to confirm the register process. Password and a “salt” value will be stored encrypted in database, with no possibility to get password decrypted back. The API will be used just for this application.
I have some questions that I need to answer before to go any further:
Which method will be the best for my application in terms of security: Basic/ SimpleMembership? Any other possibilities?
The object Principal/IPrincipal is to be used just with Basic Authentication?
As far as I know, if I use SimpleMembership, because of the use of cookies, is this not breaking the RESTful paradigm? So if I build a REST Web.API, shouldn't I avoid to use SimpleMembership?
I was checking ThinkTecture.IdentityModel, with tokens. Is this a type of authentication like Basic, or Forms, or Auth, or it's something that can be added to the other authentication types?
Thank you.
Most likely this question will be closed as too localized. Even then, I will put in a few pointers. This is not an answer, but the comments section would be too small for this.
What method and how you authenticate is totally up to your subsystem. There is no one way that will work the best for everyone. A SPA is no different that any other application. You still will be giving access to certain resources based on authentication. That could be APIs, with a custom Authorization attribute, could be a header value, token based, who knows! Whatever you think is best.
I suggest you read more on this to understand how this works.
Use of cookies in no way states that it breaks REST. You will find ton of articles on this specific item itself. Cookies will be passed with your request, just the way you pass any specific information that the server needs in order for it to give you data. If sending cookies breaks REST, then sending parameters to your API should break REST too!
Now, a very common approach (and by no means the ONE AND ALL approach), is the use of a token based system for SPA. The reason though many, the easiest to explain would be that, your services (Web API or whatever) could be hosted separately and your client is working as CORS client. In which case, you authenticate in whatever form you choose, create a secure token and send it back to the client and every resource that needs an authenticated user, is checked against the token. The token will be sent as part of your header with every request. No token would result in a simple 401 (Unauthorized) or a invalid token could result in a 403 (Forbidden).
No one says an SPA needs to be all static HTML, with data binding, it could as well be your MVC site returning partials being loaded (something I have done in the past). As far as working with just HTML and JS (Durandal specifically), there are ways to secure even the client app. Ultimately, lock down the data from the server and route the client to the login screen the moment you receive a 401/403.
If your concern is more in the terms of XSS or request forging, there are ways to prevent that even with just HTML and JS (though not as easy as dropping anti-forgery token with MVC).
My two cents.
If you do "direct" authentication - meaning you can validate the passwords directly - you can use Basic Authentication.
I wrote about it here:
http://leastprivilege.com/2013/04/22/web-api-security-basic-authentication-with-thinktecture-identitymodel-authenticationhandler/
In addition you can consider using session tokens to get rid of the password on the client:
http://leastprivilege.com/2012/06/19/session-token-support-for-asp-net-web-api/

SOA - Authentication Service design

I'm designing a Service Oriented Architecture, and I also do need an authentication service in order to recognize clients and allow them to access resources.
Actually I found two possible solutions:
sign each single request using a pubkey and privatekey
token-based authentication using pubkey and privatekey
I'm not assuming an oauth2 service since it would add too many overhead designing the system for my needs, instead I do prefer to adopt a simpler (but also strong) authentication solution.
So here I come with my AuthenticationService, that can either be queried by the client making the API request (obtaining a token to pass alongside the request) or be queried by each single API endpoint to perform a reverse check of the HMAC that signed the request to see if it matches (checking if the private key used to produce the HMAC was valid).
I can see the latest to be simpler for the final developer performing several operations, but it would also require more checks to validate the token and handle it's expiration...
What potential security issues could the token solution raise that the single-request HMAC doesn't? What do you prefer and, possibly, why?
At the end I finally designed an authentication service based on the same Amazon solution.
It requires users to sign each request using the private key. So the request will send an Authorization header with the value "PUBKEY:SIGNATURE", where the signature is a HMAC composed of any request data (it could be the request body itself) plus a timestamp, to be passed inside the Date header. This implementation is strong enough to avoid MITM and replay attacks.
For more info about this solution here is a great explanation that helped me a lot to understand the real implementation.
Hope this really help someone else in the world facing the same problem.

Should I negotiate OAuth2 auth inside digest realm?

I'm probably confusing concepts, but I've been discussing on the web2py Google Group that they should implement digest-authentication.
With OAuth2, I'm thinking that the auth-key should be hashed and only sent within an authentication realm.
If it makes a difference, I'm using JavaScript client-side, interfaces are exposed with JSONRPC server-side, and OAuth2 is done with Facebook.
Should I negotiate OAuth2 inside a digest realm?
You are confusing things - there's no notion of digest realm in OAuth. There's also no such thing as an 'auth-key'.
What you have is an auth-token, which represents a claim that you have been issued by a user/entity.
Since the token represents the [client_id, user, scope, expiration] tuple, it can not be used to produce a hash as that hash would be useless - the Resource Server cannot hash every possible combination in order to find the match.
If you want transport security, simply require SSL (not accounting for MiTM-attacks with valid certs and so on).
That said, protecting the credentials (the token) using a digest is pretty useless when the attacker is already in a position to intercept your traffic...
Also, to add something to the story behind OAuth2 - the reason it is so simple (relying on SSL for protection) is that this is something that is manageable by pretty much everyone.
The more complex something is, the higher the odds of something going wrong.

Using OAuth securely in JavaScript to save bandwidth

I want the users of my website to use Dropbox to store their files. I will be using OAuth 1.0 for this purpose. I can't use OAuth 2.0 as Dropbox only supports OAuth 1.0.
If I completely implement the authorization and file retrieval/storage at the server-side it will cost me a lot of bandwidth for the file storage/retrieval. I thought of completely shifting this to JavaScript for saving the bandwidth. However, in that case the consumer secret will be exposed to the world causing security issues.
To prevent the consumer secret exposure I have thought of performing the request_token, authorize and access_token phases at the server-side. Then pass the necessary parameters to JavaScript which will then handle storage and retrieval of files.
Is this a good idea? Or can you see any problems in it?
I think it makes perfect sense.
As long as you make absolutely sure that none of your keys/secrets appear anywhere in your JavaScript code, and make absolutely sure to only persist keys/secrets for the duration of the session you should be safe.
EDIT: You can of course persist the access token to Dropbox server side beyond the scope of the session. That way you can reuse the same access token across several sessions.
I've encountered the same issue, the only thing is if the endpoint, in your case Dropbox, supports CORS, aka returns ACCESS_CONTROL_ALLOW_ORIGIN permitting the browser to post to it. Otherwise you could post via a FORM but i dont think you'll be able to read the response.
FYI i've wrapped this into a clientside library, take a look at http://adodson.com/hello.js/ and serverside OAuth1 shim https://npmjs.org/package/oauth-shim

Resources