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.
Related
I'm attempting to implement the Client Credentials flow of OAuth 2.0 to secure a RESTful service, using Apache CXF (version 2.7.12).
My only client (for now) will be trusted to keep the key and secret confidential - I'm aware of the considerations around that.
My question is how I should store the client secret on the authorisation server. In my mind, the 'client secret' is effectively a password, and thus should be salted and hashed. However, CXF's AccessTokenService, which does the comparison between the stored secret and the value passed in on the request, only does a String.equals() comparison, and doesn't seem to give me any hook where I can provide a different mechanism.
This means that I would need to store the client secret in plain text in order to compare it against the plain text value from the request, without a slightly hacky alternative.
Am I missing some obvious functionality that would let me hash the incoming value before the comparison, or am I being overly-cautious with the client secret? Maybe I'm wrong to treat it like a password?
A sort-of answer, for people encountering this question in the future.
My approach was to create a very simple filter (as described here: http://cxf.apache.org/docs/jax-rs-filters.html), which manually creates a SecurityContext (https://cxf.apache.org/javadoc/latest/org/apache/cxf/security/SecurityContext.html), and adds it to the Message as it passes through the Filter.
This means that as the flow continues on to CXF's AccessTokenService, it's identified as already being authenticated.
I also asked a question on the CXF mailing list, and got a very prompt reply from a developer agreeing that he'd recently noticed this as a potential issue, and was looking into it. Within a few hours he'd committed a change which addressed it, and looked like it would have been an ideal solution. Unfortunately, I've still not found time to test it, as my solution works and gives me a bit of extra flexibility that's helpful for other requirements on my project.
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).
I am implementing an API in rails and would like to use HTTP digest authorization as it is more secure than basic authorization. How would one achieve this if my passwords are stored in the database as a one way cryptographic hash.
Honestly? Don't bother. If you're going to use Digest over HTTP, you might as well be using forms or basic auth. HTTPS is the solution. Using Digest is still totally insecure (it uses weak hashing and it provides no defense against MitM attacks).
HTTPS is not hard and without it you are going to have a very hard time securing your application.
The only way to use digest authorization with hash values stored on the server is to duplicate the hash algorithm on the client to turn the user's password into the hash, which then basically becomes the new password (shared secret key).
If you used a salt when generating the hash values, you'll need to use the same salt on the client, which may prove difficult.
As others have suggested, consider using HTTPS instead. You can then send the passwords in plain text from the client to the server and rely on HTTPS for the end-to-end protection. HTTPS provides both encryption and authentication, which closes the loop.
I am implementing an oauth2 solution for an API i've created and i'm struggling with the potential insecurites (or my understanding at least).
Is it correct that only a single token is generated and used as authentication credentials for an endpoint request. What's stopping a potential brute force attack where an attacker simply submits tokens to the API in the hope that one will be valid and in use?
I've probably misunderstood something but i can't get for the life in me what it is.
Tokens should be difficult to imagine of course. They should not be simple sequential integers for example. There is also no limit on the token length. There are basically two options:
1) build a long token encrypted using your own key (note: it does not have to be long, but it will since cryptography will make it long implicitly). You can check on return the token is really yours because you're the only one that can encrypt and decrypt these tokens.
2) build tokens that are also stored in your database, and are reasonably difficult to create, so you will check the tokens exists in your database.
You can also mix the two approaches. You should also add some expiration time to the tokens (either embedded in it in the 1st case, or aside the token in the database in the 2nd case).
One of the most vulnerable grant types in OAuth 2.0 for Brute Force Attack is Resource Owner Password Credentials type. In such a case, hacker has access to client credentials (clientId and password) and he/she only requires resource owner (user) credentials (username and password).
There is an authentication implementation model described in Java - Spring Security here that would shed some light to avoid this issue.
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.