Thursday, September 6, 2012

The Story About Two OAuth2 Vulnerabilities

Facebook Connect Reply Attack
There is a blatant issue in facebook connect. It's vulnerable to replay attack.

Authorization 'code' expires as soon as access_token expires - approximately 60-80 minutes, during this period it can be used many times to obtain access_token. Every time you visit example.org/fb_callback?code=123qwe... you are authenticated for example.org.

FB Connect doesn't follow clear and concise countermeasures from Threat Model. Here they are with annotations:
   o  Limited duration of authorization codes - Section 5.1.5.3 [60-80 minutes are more than enough]
   o  The authorization server should enforce a one time usage restriction (see Section 5.1.5.4). [unlimited]
There are couple of ways to get 'code':
Logs. 
For example if you use omniauth with rails check your logs for
GET "/auth/facebook/callback?code=..."
I recommend to filter this parameter with built-in tool:
config.filter_parameters += [:password, :code]
Sniff
Callback is located on Client's website - and it is not always HTTPS. Your URL with code may be sniffed with MITM, browser plugins, browser history(if it has not redirects) etc
XSS
Here is a neat exploit to extract callback URL for proper redirect_uri.

<iframe src="https://www.facebook.com/dialog/permissions.request?app_id=159618457465836&display=page&next=http://magru.net/users/auth/facebook/callback&response_type=code" name="refcontainer" onload="alert(refcontainer.document.referrer)"></iframe>

1) Load authorize URL with proper redirect_uri as callback in iframe
2) get redirected on proper redirect_uri with code
3) another redirect, usually to root
4) fires up 'onload' event
5) since we are on the same origin we just go into iframe and extract 'document.referrer' - redirect_uri with code.
6) leak code and use it for replay attacks.

Mitigation:
One time usage of 'code', please. There is no sense to keep 'code' if Client already obtained access_token for it.

Vkontakte Referrer Leak
Vkontakte has one time usage of 'code'. No replay attack here... Wait, there is a similar one. VK OAuth2 has a huge flaw.
They do not require 'redirect_uri' to exchange code for token. It means there is no verification, was certain 'code' issued for proper redirect_uri or any other URL (on Client's domain).
You can get a code for
SITE.com/fake_callback_leaking_referrer?code=123qwe
and then just use it on
SITE.com/real_callback?code=123qwe
You will be authenticated.

There are literally dozens of ways to leak code: browser history, hot linked images leak referrer, clickjacking with clicking on external URL, sniffing, open redirectors(feature on some sites site.com?url=http://other.com) etc


Mitigation:
Every time you create code you must save for which redirect_uri it was issued. When code will be exchanged for token, ensure that given redirect_uri parameter is equal stored.

Result

Fixed on facebook, 2 grands $ bounty, fixed on vkontakte (for new apps only).

2 comments:

  1. What does "for new apps only" mean in particular?

    ReplyDelete
    Replies
    1. I don't know. Vkontakte has quite shitty documentation. I assume it means the fix is applied for apps registered after september 6, maybe.
      but people say their fix was fucked up and sites like loginza.ru failed to login with VK. Just epic fail

      Delete