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 you are authenticated for

FB Connect doesn't follow clear and concise countermeasures from Threat Model. Here they are with annotations:
   o  Limited duration of authorization codes - Section [60-80 minutes are more than enough]
   o  The authorization server should enforce a one time usage restriction (see Section [unlimited]
There are couple of ways to get 'code':
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]
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
Here is a neat exploit to extract callback URL for proper redirect_uri.

<iframe src="" 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.

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
and then just use it on
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 etc

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.


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