8

I am considering OpenID as a login method for my PHP application, but there is one thing that prevents me from continuing: how can I protect an OpenID consumer against abuse?

An example of abusing OpenID by using a consumer as proxy

Abuse includes flooding other servers with requests, using my application as a proxy, passing a large download as URL or unnecessarily slowing down the server by doing a lot requests.

I guess I should implement rate-limiting on doing requests, but how am I supposed to do that? Possible attackers could use other proxies or TOR for bypassing IP checks. Limiting the providers which are allowed would be against the principles of OpenID right?

I do not expect my users to be evil, but I'd like to know which things I need to take into account before adding another possible attack vector.

Should it matter, I'm about to use lightopenid as back-end for the PHP application.

Lekensteyn
  • 64,486
  • 22
  • 159
  • 192

3 Answers3

3

You need to separate the attacks into two pools. 1) Attacks against your own site, and 2) Attacks against someone else using you as a proxy. Neither of these issues are new or unique to OpenID. For example the classic "tell a friend" email forms could be automated to send out email spam from the proxy party's IP address and email, shielding the spamming party from consequences and providing them with a (potentially) clean IP/email that isn't already flagged by spam protection. This was primarily addressed with the "CAPTCHA" to prevent automated use of the form.

For attacks against your own site, this has all been covered countless times before. Try here: protect your self against DOS attacks

For attacks against someone else's site, many of the same principals apply as mentioned in that other question. Throttle authentication requests, reject unreasonable or malformed requests, verify the Content-Length header against actually content on POST back and of course you can always add the classic "CAPTCHA" to help prevent automated attacks using your OpenID consumer.

Also contrary other suggestions here, I wouldn't throttle based on the OpenID TLD, but rather the requesting party's IP address. Yes people can rent proxy IPs, but you can't fairly throttle based on the TLD as the userbase for each OpenID provider will vary widely. You can also purchase a database of known proxy IPs from a company like MaxMind. If the user is coming from a proxy IP, increase the aggressiveness of your throttling.

Community
  • 1
  • 1
BenSwayne
  • 16,810
  • 3
  • 58
  • 75
  • The client IP address seems to be a good thing to use, probably using the C-class part to further decrease the abuse chance. – Lekensteyn Oct 25 '11 at 09:14
0

Slow down requests proportionally to the number of times a certain domain has been requested.

For example, suppose that somebody tries to use you to DOS the server example.com by requesting many URLs like http://example.com/foo, http://example.com/bar, http://example.com/foobar120382. Consider all this requests as requests for example.com and execute the first request without any delay. Delay 2 seconds before making the next request, delay 4 seconds before making the third request, delay 8 seconds before making the forth request, 16 before the fifth and so on.

Such little delays are pretty much unnoticed by human users but will highly reduce the ability of your server to act as a DOSsing proxy. Just think that the 12th request will be blocked for more than one hour (if you use powers of two).

Obviously you should also create some kind of white- or gray-list for common large OpenID providers like Google or myOpenID. Those domains are likely to be requested very often.

gioele
  • 9,748
  • 5
  • 55
  • 80
  • Delaying in that way would probably DOS my own server which is another thing I'm trying to avoid. – Lekensteyn Oct 21 '11 at 21:02
  • Why? Just put these request in an async queue, maybe with something like http://stackoverflow.com/questions/124462/asynchronous-php-calls. – gioele Oct 21 '11 at 21:13
  • That won't work since I need to verify the response of the other side which is why the request is sent in the first place. Also, it does not protect against servers which do not reply (that needs a smaller time-out) – Lekensteyn Oct 21 '11 at 21:26
  • I do not understand. 1) you get the request to authenticate 2) you wait for few seconds 3) you do what you would do anyway (a call to some lightopenid functions, I suppose). Why should this break anything? It is just like having a slow server or a slow network. – gioele Oct 21 '11 at 21:31
  • Wouldn't I need to find the canonical URL to connect to? http://stackoverflow.com/q/353880/427545 – Lekensteyn Oct 21 '11 at 21:47
  • Well, you need to do that, but that is in step 3, let the library do that. All you need to do is 1) receive the OpenID URL from a form (I suppose you already have something like that already up), 2) analyse that URL to understand which delay should be applied and 3) finally call the library to do all the work. – gioele Oct 21 '11 at 22:14
  • Consider step 4 on page 4 of [this PDF](http://www.nds.rub.de/media/nds/veroeffentlichungen/2010/12/20/CameraReady_SecurityofSingleSignOn.pdf). To quote: "The Relying Party performs discovery upon the received Identifier i.e. retrieves the data resource held at an Identifier’s url and [..]". That discovery must be done by the consumer (the RP), it cannot be postponed or the consumer won't know which server it needs to communicate with (in both directions, i.e. obtaining the login URL and verifying the tokens). – Lekensteyn Oct 22 '11 at 08:59
  • You can be used as a DOS proxy in two ways: either you DOS the Identifier domain or you DOS the Relying party. In the first case the attacker does not "control" the destination domain. Slowing down as the number of requests for this Identifier increases will solve this case. In the second case it controls a lot of Identifier domains (hard to believe) and makes all of them point to the same domain to DOS. If you are worried about this case you should add a similar delay to the library. In the Wincert case all the attacks were of the first case: directed to the Identifier, not the RP domain. – gioele Oct 22 '11 at 12:38
  • Be aware that everyone can setup their own provide which does not take a lot efforts at all. A single wildcard domain can be used for this purpose. That can probably be solved by using the canonical domain name only (e.g. `example.com` for `www.Example.Com`), but getting a set of domain names is not that difficult. In the Wincert case, the goal was to open the other websites. The attackers of course do not care that the wincert server got slowed as a result. Using delaying, it's even simpler to DOS the RP because the attacker just has to send some URLs which make the server wait. – Lekensteyn Oct 22 '11 at 13:20
0

I would do something simpler. Limit the OpenID endpoints to a limited set of trusted ones: Google, wordpress, myopenid, yahoo. It will probably cover most of the users, and will not make it possible for bots to make your site generate traffic to random sites.

Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • That would be fine for a private application, but this is against the open nature of OpenID. When the mechanism is strongly abused, it's probably useful to have a flag for allowing access to common services though. – Lekensteyn Oct 25 '11 at 15:44
  • well, for non-private application it would also be fine. Yes, it would go against the open nature, but in reality I think few people are using an openid outside the major providers – Bozho Oct 25 '11 at 16:00