Blog

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:

  1. Application requests graph.facebook.com/oauth/device?type=device_code&client_id=1

    to retreive a hash code and user_code

  2. The application tells the user to go to facebook.com/device and input the user_code

  3. 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.

  4. 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:

  1. The attacker requests graph.facebook.com/oauth/device?type=device_code&client_id=1 to get the user_code (abcd) and hash code (4567)

  2. 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
  3. The /dialog/oauth will redirect to

    https://m.facebook.com/device.php?userCode=abcd&code=aZx...

    which will succeed

  4. 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:

Facebook device flow re-confirmation

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

Facebook has issued a $5000 bounty for this bug.

Random blog post

Bug bounties

Facebook CSRF leading to full account takeover (fixed)

Read more