Bug bounties
Stealing Facebook access_tokens using CSRF in device login flow
Facebook has published a way to use OAuth on Internet of Things devices, called Facebook Login for Devices. You can read the documentation here. The usual flow is:
-
Application requests graph.facebook.com/oauth/device?type=device_code&client_id=1
to retreive a hash code and user_code
-
The application tells the user to go to facebook.com/device and input the user_code
-
The user inputs the code and verifies the application through usual OAuth flow. user_code is then connected to application code.
https://www.facebook.com/v2.5/dialog/oauth?redirect_uri=https%3A%2F%2Fm.facebook.com%2Fdevice.php%3FuserCode%3D{$user_code}&client_id=1234
This is the mobile version of device login flow - redirect_uri points to a mobile domain.
-
The application can now request graph.facebook.com/oauth/device?type=device_token&client_id=1&code=hash_code
to gain the user access_token
The problem lies in step number 3: when user_code is connected to application_code, it is done like so:
https://m.facebook.com/device.php?userCode=$userCode&code=$appCode
As you can see, there is no CSRF protection, so I started building my proof of concept around that:
-
The attacker requests graph.facebook.com/oauth/device?type=device_code&client_id=1 to get the user_code (abcd) and hash code (4567)
-
Present a page to victim which will load
https://www.facebook.com/v2.5/dialog/oauth?redirect_uri=https%3A%2F%2Fm.facebook.com%2Fdevice.php%3FuserCode%3Dabcd&client_id=1234
-
The /dialog/oauth will redirect to
https://m.facebook.com/device.php?userCode=abcd&code=aZx...
which will succeed
-
The attacker now requests graph.facebook.com/oauth/device?type=device_token&client_id=1&code=4567
to get the access_token of the victim.
To exploit this, attacker would need to know the victim has approved an application which has “Login for Devices” enabled, which makes it fairly hard to abuse - this is a perfect storm vulnerability.
Through further testing, I found out that every app which has “Login from Devices” enabled, and “Web OAuth Login” disabled gets “m.facebook.com/device.php” automagically added as a valid redirect_uri.
Theoretically, if a pre-approved official Facebook application is made for the future iToaster, this bug could have lead to info disclosure on any Facebook account, and perhaps more, depending on the app permissions. It was a long shot, and I found no such application (thanks @phwd for help here).
Facebook has fixed this first by adding a re-confirmation prompt every time you try to use device login, and later by implementing CSRF protection through "state" OAuth parameter:
The timeline:
-
December 8, 2015: Bug reported
-
December 9, 2015: Additional information sent, along with a proof of concept page
-
December 11, 2015: Facebook confirms the vulnerability
-
February 1, 2016: I ask for updates about the report
-
February 10, 2016: Facebook informs me they have fixed the issue
-
February 10, 2016: Nope, message was sent in error
-
February 18, 2016: Bug is now fixed
Random blog post
Bug bounties