Blog Bug bounties Stealing Facebook access_tokens using CSRF in device login flow written on July 19th, 2016

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: