Intermittent token failure with load balanced oAuth - oauth

We have implemented our own oAuth provider and are having an issue when the system runs in a load balanced scenario. When we run with a single server all is well but when we switch the other on we get the following situation:
Token ‘A’ generated on server 1
Token ‘A’ not valid on server 2.
I have done some Googling on this and it seems to be a known issue but can’t seem to find a solution.
Anybody got an idea.
Thanks

You will have to make sure that you do one of:
synchronize the state of your Authorization Server between all load balanced nodes by using a shared cache (e.g. database or file system) or replicates state across nodes using some replication mechanism
your Authorization Server issues tokens that can be inspected by the load balancer to find out to which node it needs to send the validation request
The latter. has the downside that it cannot be used in a high availability scenario.

Related

Locking an API to App-Use only

I've written a rails back-end for the mobile app I'm working on and it occured to me that even though I'm using token authentication, anyone could write a malicious script that continually registers users / continually makes requests in attempts to fill the database / attack the server.
I guess there are two questions here:
1) What modifications would I need to make in order to ONLY allow API access from my mobile app
2) How can I protect my API urls?
Thanks :)
There are multiple things you can do to protect your API :
The simplest thing you can start with is verifying the user-agent header in your request. That usually gives you a good indicator of what the initiating device is.
That being said, it isn't always accurate and its definitely fakeable.
If you control the client side of the mobile app as well, you could encrypt the requests/responses with a cypher or key system which requires a key that only your mobile-app knows. Look at openssl for that... using a public/private key pair.
Token authentication is a good idea. I would actually look at oAuth or similar systems for authentication and keep your session timers short.
On top of that, you can probably add some rate control in order to limit consecutive calls from the same IP in a given timespan.
Finally, I would look at something like "fail2ban" or similar to automatically ban brute-force type attacks.

Losing Authentication Details (ClaimsIdentity)

I have an application with claims based authentication and recently I have been having an issue where at random I lose authentication. The application usually gets it's Identity, Claims information from System.Security.Claims.ClaimsIdentity and it authorizes fine. For some reason after clicking around different pages I lose authentication and it seems to be looking in System.Security.Claims.WindowsIdentity and it exits with a null exception as there is now no more authorization information. I am also using IdentityServerV3. I apologise for the lack of specific technical data but was wondering if anyone has ever had this issue. There is no specific time that this does this after as I first thought it might be expiring. It happens very randomly. I have included screen grabs:
This was when I was authorized
and this was 10 seconds later
If you need any further infromation let me know and thanks in advance!
I had similar issue where losing authentication randomly, caused by three reasons I can remember,
1) multiple threading - code was executed by a different thread that doesn't have identity context
2) cookie size exceeded browser limit authentication cookie get chunked when pass back to server
3) identity server hosted in multiple instances and identity server configured to store token in memory.
Regarding your case, my gut feel which might be completely red herring, is the 1) which the thread executing your code 10 sec later is under a different identity context , I would suggest try to verify any path of your code can by multiple threading first, at the mean time check the thinktecture log that can be found in output window if you are using default logging provider to see if anything suspicious
Hope it helps

HTTPS POST Security level

I've searched for this a bit on Stack, but I cannot find a definitive answer for https, only for solutions that somehow include http or unencrypted parameters which are not present in my situation.
I have developed an iOS application that communicates with MySQL via Apache HTTPS POSTS and php.
Now, the server runs with a valid certificate, is only open for traffic on port 443 and all posts are done to https://thedomain.net/obscurefolder/obscurefile.php
If someone knew the correct parameters to post, anyone from anywhere in the world could mess up the database completely, so the question is: Is this method secure? Let it be known nobody has access to the source code and none of the iPads that run this software are jailbreaked or otherwise compromised.
Edit in response to answers:
There are several php files which alone only support one specific operation and depend on very strict input formatting and correct license key (retreived by SQL on every query). They do not respond to input at all unless it's 100% correct and has a proper license (e.g. password) included. There is no actual website, only php files that respond to POSTs, given the correct input, as mentioned above. The webserver has been scanned by a third party security company and contains no known vulnerabilities.
Encryption is necessary but not sufficient for security. There are many other considerations beyond encrypting the connection. With server-side certificates, you can confirm the identity of the server, but you can't (as you are discovering) confirm the identity of the clients (at least not without client-side certficates which are very difficult to protect by virtue of them being on the client).
It sounds like you need to take additional measures to prevent abuse such as:
Only supporting a sane, limited, well-defined set of operations on the database (not passing arbitrary SQL input to your database but instead having a clear, small list of URL handlers that perform specific, reasonable operations on the database).
Validating that the inputs to your handler are reasonable and within allowable parameters.
Authenticating client applications to the best you are able (e.g. with client IDs or other tokens) to restrict the capabilities on a per-client basis and detect anomalous usage patterns for a given client.
Authenticating users to ensure that only authorized users can make the appropriate modifications.
You should also probably get a security expert to review your code and/or hire someone to perform penetration testing on your website to see what vulnerabilities they can uncover.
Sending POST requests is not a secure way of communicating with a server. Inspite of no access to code or valid devices, it still leaves an open way to easily access database and manipulating with it once the link is discovered.
I would not suggest using POST. You can try / use other communication ways if you want to send / fetch data from the server. Encrypting the parameters can also be helpful here though it would increase the code a bit due to encryption-decryption logic.
Its good that your app goes through HTTPS. Make sure the app checks for the certificates during its communication phase.
You can also make use of tokens(Not device tokens) during transactions. This might be a bit complex, but offers more safety.
The solutions and ways here for this are broad. Every possible solution cannot be covered. You might want to try out a few yourself to get an idea. Though I Suggest going for some encryption-decryption on a basic level.
Hope this helps.

How to use Struts 2 Token Tag correctly in a distributed Java environment?

Struts 2 support stop double-submission of forms by generate a unique random token and store it in the session, and use token tag pass the token to the client form then verify the tokens from session and form.
As far as i know, this solution can only work in a single JVM because the session is separated from each other. I cannot find something useful about how to use this solution in a distributed Java environment. We use Nginx proxy HTTP requests to multiple JVMs and Nginx does not guarantee to proxy the same request to the same JVM every time.
Can someone give me some help?
BTW, i am trying to use this solution to stop CSRF attack.
You have two choices (neither of which really has anything to do with Struts 2, but has everything to do with session management in a distributed environment):
Use Session Affinity - so when a user creates a session, Nginx remembers which backend server the user went to, and that session is bound to that server for all subsequent requests. (This is the more typical solution). might get you started.
Depending on your application server, there may be the possibility of sharing the session data between servers. For example, in Tomcat 6, the configuration directions are.

Implementing a 2 Legged OAuth Provider

I'm trying to find my way around the OAuth spec, its requirements and any implementations I can find and, so far, it really seems like more trouble than its worth because I'm having trouble finding a single resource that pulls it all together. Or maybe it's just that I'm looking for something more specialized than most tutorials.
I have a set of existing APIs--some in Java, some in PHP--that I now need to secure and, for a number of reasons, OAuth seems like the right way to go. Unfortunately, my inability to track down the right resources to help me get a provider up and running is challenging that theory. Since most of this will be system-to-system API usage, I'll need to implement a 2-legged provider. With that in mind...
Does anyone know of any good tutorials for implementing a 2-legged OAuth provider with PHP?
Given that I have securable APIs in 2 languages, do I need to implement a provider in both or is there a way to create the provider as a "front controller" that I can funnel all requests through?
When securing PHP services, for example, do I have to secure each API individually by including the requisite provider resources on each?
Thanks for your help.
Rob, not sure where you landed on this but wanted to add my 2 cents in case anyone else ran across this question.
I more or less had the same question a few months ago and hearing about "OAuth" for the better part of a year. I was developing a REST API I needed to secure so I started reading about OAuth... and then my eyes started to roll backwards in my head.
I probably gave it a good solid day or 2 of skimming and reading until I decided, much like you, that OAuth was confusing garbage and just gave up on it.
So then I started researching ways to secure APIs in general and started to get a better grasp on ways to do that. The most popular way seemed to be sending requests to the API along with a checksum of the entire message (encoded with a secret that only you and the server know) that the server can use to decide if the message had been tampered with on it's way from the client, like so:
Client sends /user.json/123?showFriends=true&showStats=true&checksum=kjDSiuas98SD987ad
Server gets all that, looks up user "123" in database, loads his secret key and then (using the same method the client used) re-calculates it's OWN checksum given the request arguments.
If the server's generated checksum and the client's sent checksum match up, the request is OK and executed, if not, it is considered tampered with and rejected.
The checksum is called an HMAC and if you want a good example of this, it is what Amazon Web Services uses (they call the argument 'signature' not 'checksum' though).
So given that one of the key components of this to work is that the client and server have to generate the HMAC in the same fashion (otherwise they won't match), there have to be rules on HOW to combine all the arguments... then I suddenly understood all that "natural byte-ordering of parameters" crap from OAuth... it was just defining the rules for how to generate the signature because it needed to.
Another point is that every param you include in the HMAC generation is a value that then can't be tampered with when you send the request.
So if you just encode the URI stem as the signature, for example:
/user.json == askJdla9/kjdas+Askj2l8add
then the only thing in your message that cannot be tampered with is the URI, all of the arguments can be tampered with because they aren't part of the "checksum" value that the server will re-calculate.
Alternatively, even if you include EVERY param in the calculation, you still run the risk of "replay attacks" where a malicious middle man or evesdropped can intercept an API call and just keep resending it to the server over and over again.
You can fix that by adding a timestamp (always use UTC) in the HMAC calculation as well.
REMINDER: Since the server needs to calculate the same HMAC, you have to send along any value you use in the calculation EXCEPT YOUR SECRET KEY (OAuth calls it a consumer_secret I think). So if you add timestamp, make sure you send a timestamp param along with your request.
If you want to make the API secure from replay attacks, you can use a nonce value (it's a 1-time use value the server generates, gives to the client, the client uses it in the HMAC, sends back the request, the server confirms and then marks that nonce value as "used" in the DB and never lets another request use it again).
NOTE: 'nonce' are a really exact way to solve the "replay attack" problem -- timestamps are great, but because computers don't always have in-sync timestamp values, you have to allow an acceptable window on the server side of how "old" a request might be (say 10 mins, 30 mins, 1hr.... Amazon uses 15mins) before we accept or reject it. In this scenario your API is technically vulnerable during the entire window of time.
I think nonce values are great, but should only need to be used in APIs that are critical they keep their integrity. In my API, I didn't need it, but it would be trivial to add later if users demanded it... I would literally just need to add a "nonce" table in my DB, expose a new API to clients like:
/nonce.json
and then when they send that back to me in the HMAC calculation, I would need to check the DB to make sure it had never been used before and once used, mark it as such in the DB so if a request EVER came in again with that same nonce I would reject it.
Summary
Anyway, to make a long story short, everything I just described is basically what is known as "2-legged OAuth". There isn't that added step of flowing to the authority (Twitter, Facebook, Google, whatever) to authorize the client, that step is removed and instead the server implicitly trusts the client IF the HMAC's they are sending match up. That means the client has the right secret_key and is signing it's messages with it, so the server trusts it.
If you start looking around online, this seems to be the preferred method for securing API methods now-adays, or something like it. Amazon almost exactly uses this method except they use a slightly different combination method for their parameters before signing the whole thing to generate the HMAC.
If you are interested I wrote up this entire journey and thought-process as I was learning it. That might help provide a guided thinking tour of this process.
I would take a step back and think about what a properly authenticated client is going to be sending you.
Can you store the keys and credentials in a common database which is accessible from both sets of services, and just implement the OAuth provider in one language? When the user sends in a request to a service (PHP or Java) you then check against the common store. When the user is setting up the OAuth client then you do all of that through either a PHP or Java app (your preference), and store the credentials in the common DB.
There are some Oauth providers written in other languages that you might want to take a look at:
PHP - http://term.ie/oauth/example/ (see bottom of page)
Ruby - http://github.com/mojodna/sample-oauth-provider
.NET http://blog.bittercoder.com/PermaLink,guid,0d080a15-b412-48cf-b0d4-e842b25e3813.aspx

Resources