After finishing a WCF SOAP webservice which employs DotNetOpenAuth, it occured to me that once a consumertoken is stored in the OAuthConsumer table it is never deleted, not even after the token is considered expired.
I have edited the DotNetOpenAuth project's standard AuthorizedConsumers.aspx page so that users can manually revoke access to an application, basically deleting the consumertoken from the database, but I was wondering if it shouldn't be possible to have old tokens removed automatically. For example, when the user attempts to access the application which the token grants access to, shouldn't there be some sort of check to see if there isn't already a token, and if there is, whether it's expired or not, removing the old token if it is expired, before making a new one?
I don't actually know if there are any checks already in place (I did look for them but can't find them), are there? And how would I go about adding code to remove expired tokens from the database? Where exactly would I insert that code? In the StoreNewRequestToken method of the DataBaseTokenManager class?
Thank you!
Cleaning your database tables is beyond the scope of DotNetOpenAuth. You can implement it however you like. For instance, you might have a database stored procedure that removes token rows that have expired and invoke it on a timer somehow. DotNetOpenAuth expects you to only return valid (non-expired) tokens from your implementation of a token manager interface. The expiration of these tokens is given to you when DNOA first asks you to store them.
As for avoiding your tokens table growing too large, there are a couple of approaches. You can use short-lived tokens and be sure to clean your tables periodically. But the best approach is used in DotNetOpenAuth's OAuth 2 implementation, so if you can switch to OAuth 2 then that's ideal. Once you're there, you'll discover there is no token table at all. The closest thing you have is an Authorizations table, which only has a row for every individual user approval gesture, and you can remove them when (and if) those authorizations ever expire. With that authorization, clients can obtain as many unique tokens as they want and your database never grows because the tokens are self describing and signed. And DNOA manages it all for you.
Related
I want to invalidate refresh jwt token without maintaining a blacklist of used refresh tokens with rotations, for this I had the idea of including a ValidationCode in the payload of the RT that the server generates and store whenever 2 refresh tokens are detected being in use with different rotation number (As an example RT2 that the normal user got from his last request and RT3 that the malicious user generated after sending a malicious request using the old RT2).
Once the server finds that a RT2 is in use while the latest one is RT3. The server should "Invalidate" the previous tokens, and issue a new RT when the user reconnects using his password etc. The process of invalidating token is simply changing the ValidationCode in the newly generated token, and accepts any request in which the token is valid + the validation code in the payload matches the one stored in the server for that user.
If Using this approach, if the malicious user try to use RT3 again, even if the jwt token is valid, the ValidationCode now changed and it will not match the one in the server however the newly generated tokens will.
Is this approach secure and good enough to replace blacklisting old tokens? which I think defies the purpose of using jwt at first + wasting time and memory storing the list and querying in the database
What you're describing here is a solution where you can just keep the latest RT used by the user in the database and allow only refresh requests with the RT saved in the DB. This is a valid approach but it has one drawback: you can have only one active pair of AT/RT for the user. If that is OK for you then you can go with this solution.
wasting time and memory storing the list and querying in the database
Either way you will have to query the database, so that doesn't change much. What you gain is a bit of storage space.
I have a central 'hub' containing the data for multiple organisations, each of which contain multiple users. Organisations and users are grouped together, along with 'client_credentials', under a 'Project'.
The user can authenticate using the 'password' grant type, and they obtain access & refresh token, as per the OAuth2 spec. Both are JWT.
The issue I have is correctly attributing the refresh token withe the relevant user in the 'correct' way so that I can issue a JWT access_token with the correct content.
When requesting the original tokens, I pass and validate both the client credentials and the user's username/password. Two identical (other than expiry time) tokens are generated containing the user_id and other bits. One for access, one for refresh.
So when validating the refresh token, I see (unless my understanding is wrong) a few ways of making this happen:
On the initial request, store the refresh_token against the user's database record, and do a lookup based on the association with the client credentials as well as this stored token. OR:
Generate the new access token from the unpacked refresh_token, just with a new expiry date - meaning I don't need to actually persist these things.
In some ways, the first approach seems ok, apart from my reluctance to perform database queries using any type of password/token, as typically I'd never index these fields.
And in other ways, the second approach seems ok as it doesn't actually require me to persist sensitive tokens unless I explicitly want to mark it for revocation - but it does somewhat require that the access_token and refresh_token are kept pretty much the same.
Any steer on which is the 'correct' approach, or does anyone have any alternatives?
Using the Password Grant type, you are generating/receiving two tokens: Access Token and Refresh Token. These tokens should be stored securely either in a memory table in your application or in a database. If you are using an autoscaling or fault-tolerant design, you need to use a database.
Once you have the tokens, you create an opaque random number (usually 128-bit, sometimes 64-bit), let's call it AUTH_ID. The tokens plus expiration are indexed by this AUTH_ID. You store the AUTH_ID in the client browser's session or return with the tokens. If there is a design already in place, then you will need to create a method to search the database to match the tokens passed to you. If the user does not actually require tokens, give them the AUTH_ID instead.
When the client makes a request to you, extract the AUTH_ID from the client session and lookup the tokens. If a token will soon expire, refresh it and store the new token. Then continue with the client's request.
The contents of a Refresh Token is implementation-specific. This means that if you want to rely upon information about a Refresh Token (or an Access Token) you must store that information alongside the token. Some tokens are Signed-JWT, some are Opaque.
I am developing an oAuth2 server and I've stumbled upon this question.
Lets suppose a scenario where my tokens are set to expire within one hour. On this timeframe, some client goes through the implicit auth fifty times using the same client_id and same redirect_uri. Basically same everything.
Should I give it the same accessToken generated on the first request on the subsequent ones until it expires or should I issue a new accessToken on every request?
The benefits of sending the same token is that I won't leave stale and unused tokens of a client on the server, minimizing the window for an attacker trying to guess a valid token.
I know that I should rate-limit things and I am doing it, but in the case of a large botnet attack from thousands of different machines, some limits won't take effect immediately.
However, I am not sure about the downsides of this solution and that's why I came here. Is it a valid solution?
I would rather say - no.
Reasons:
You should NEVER store access tokens in plain text on the Authorization Server side. Access tokens are credentials and should be stored hashed. Salting might not be necessary since they are generated strings anyway. See OAuth RFC point 10.3.
Depending how you handle subsequent requests - an attacker who knows that a certain resource owner is using your service and repeat requests for the used client id. That way an attacker will be able to impersonate the resource owner. If you really return the same token then at least ensure that you authenticate the resource owner every time.
What about the "state" parameter? Will you consider requests to be the "same" if the state parameter is different? If no then a botnet attack will simply use a different state every time and force you to issue new tokens.
As an addition - generally defending against a botnet attack via application logic is very hard. The server exposing your AS to the internet should take care for that. On application layer you should take care that it does not go down from small-bandwidth attacks.
You can return the same access_token if it is still valid, there's no issue with that. The only downside may be in the fact that you use the Implicit flow and thus repeatedly send the - same, valid - access token in a URL fragment which is considered less secure than using e.g. the Authorization Code flow.
As a thumb rule never reuse keys, this will bring additional security in the designed system in case of key capture
You can send different access token when requested after proper authentication and also send refresh token along your access token.
Once your access token expires, you should inform user about that and user should re-request for new access token providing one-time-use refresh token previously provided to them skipping need for re-authentication, and you should provide new access token and refresh token.
To resist attack with fake refresh token, you should blacklist them along with their originating IP after few warnings.
PS: Never use predictable tokens. Atleast make it extremely difficult to brute force attacks by using totally random, long alpha-numeric strings. I would suggest bin2hex(openssl_random_pseudo_bytes(512)), if you are using php.
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 am looking at using Savon to consume a SOAP API. One of the requirements of this particular API is that an authentication token be supplied in each request to the API. That is, apart from the request that returns the authentication token itself. That call just needs a username and password. The token expires after 20mins of inactivity.
My question is, what is the best practice for storing this token? It's surely not advisable to make two requests every time, one for the token and one for the actual request?
I was considering storing it in a session variable but this would mean generating a new token for each visitor, which I presume is not necessary. However, it would mean I could set a 20 minute expiry on it very easily though.
If I store it in the database, how would I know whether or not it will have expired before making the call to the API, without a lot of extra logic?
Or, should I store it in the database and simply make a background call to the API every few minutes to ensure the token never expires?
Or am I barking up completely the wrong tree?!
Thanks for any advice.