Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to securely authorize a user via Facebook's Javascript SDK

I want to let users log in on my website using their Facebook ID without reloading the page. This is why I use Facebook Javascript SDK. This scheme describes the authorization flow with this SDK: enter image description here

At the end of the process I know that the user is logged in and I know their Facebook ID. I can then register them in my database via this ID, and let them use it to log in afterwards.

However, this seems terribly insecure. In order to let my server-side script know the user's ID, I have to send it via AJAX. However, I have no way of knowing whether it's the owner of the ID who's trying to log in. Anyone can send the POST request with an ID (especially of one gets hold of another user's ID).

My current idea is to let the user log in via JS SDK as usual, send the ID and Access Token via AJAX to the server and then use cURL in the PHP script to ensure the user is actually logged in.

Is this the way to go, or am I overlooking better alternatives?

like image 204
sbichenko Avatar asked Jan 06 '13 20:01

sbichenko


People also ask

What is Facebook SDK for JavaScript?

The Facebook SDK for JavaScript provides a rich set of client-side functionality that: Enables you to use the Like Button and other Social Plugins on your site. Enables you to use Facebook Login to lower the barrier for people to sign up on your site. Makes it easy to call into Facebook's Graph API.

How do I set up OAuth on Facebook?

In the App Dashboard, choose your app and scroll to Add a Product Click Set Up in the Facebook Login card. Select Settings in the left side navigation panel and under Client OAuth Settings, enter your redirect URL in the Valid OAuth Redirect URIs field for successful authorization.

Where is the security and login settings on Facebook?

Tap in the top right of Facebook. Scroll down and tap Settings, then tap Password and security. Go to the section WHERE YOU'RE LOGGED IN. You may need to tap See more to see all of the sessions where you're logged in.

What client OAuth settings Facebook?

Web OAuth Login settings enables any OAuth client token flows that use the Facebook web login dialog to return tokens to your own website. This setting is in the Products > Facebook Login > Settings section of the App Dashboard.


2 Answers

  1. You don't need to push the user's ID via ajax. You should, on the server side, use the fbsr_{app_id} cookie which holds the signed_request. Parse this signed_request using your 'secret' app_secret issued by FB to get the 'user_id'. NOTE: a successful parse also shows that the cookie data provided by FB is not tampered with.

  2. Once you parse the signed_request, you should also get the 'issued_at' time. Check that this time is within the last 10 mins. By doing this, you know that the login request hit your server as the user (with user_id) used client-side SDK. (Refer: http://developers.facebook.com/roadmap/completed-changes/)

  3. You should immediately exchange this code for an access_token. If this fails (FB will give you an error message of type OAuthException), it means that there was an unnatural delay between user signing in to facebook and you getting the login request.

With step #2, you can thwart attempts of an attack using old fbsr_ cookie. If the user (from user_id) already has an account with you, then you may wish to stop here and login the user. However, there may be scenarios where your app_secret may be compromised. To take care of this case, you should follow step #3, as the exchange of code for access_token can happen only once and within 10 mins of it's issue. If the user doesn't have an account with your site, then you anyway need step #3 to use the access_token for retrieving other necessary user data, like name, email, etc from FB.

Therefore, someone else stealing the victim's cookie and trying to attack is possible only within this 10 min security gap. If you are unhappy with this security hole, you should migrate to server-side authentication. The decision depends on the sensitivity of the user information you store. And you don't compromise anything moving to server-side auth, you can simultaneously continue to use client-side methods for other things.

like image 59
Ethan Avatar answered Oct 11 '22 18:10

Ethan


Once you've logged in a user via the JS SDK, a special cookie will be setup containing credential info (encoded with your secret key if I'm correct). This info can then be used via the PHP SDK getUser() method.

As long as your API (your ajax endpoint) is on the same domain as your app, you should receive this cookie whenever the user request your server.

Of course, you need to make sure the Javascript SDK is setup correctly and that you used the cookie: true config option, and that you give a valid channel file. If these requirement ain't met, you may have some trouble with cross-domain communication and 3rd party cookie in IE and Safari.

You can also check this related question: A proper approach to FB auth

like image 23
Simon Boudrias Avatar answered Oct 11 '22 17:10

Simon Boudrias