views:

223

answers:

3

According to the Facebook API documentation, most of the work is handled through javascript.

That means that all the processing is done, and then the front end checks if the user is connected to Facebook/authorized. right?

My question is:

Suppose a user goes to my site for the first time ever. He clicks on "facebook connect". The javascript verifies him as authentic, and it "redirects" to another page on my server. From then on, how do I know that the user is actually authenticated to my website, since everything is done on frontend?

I think this is correct, but aren't there some security issues..:

-After user clicks Login, Facebook redirects to a page on my site. AND they also create a cookie with a specific "Facebook ID" that is retrieved only from this user. My backened will "read" the cookie and grab that ID...and then associate it to my userID.

If that is correct...then it doesn't make sense. What if people steal other people's "facebook ID" and then forge the cookie? And then my backend sees the cookie and thinks it's the real user...?

Am I confused? If I am confused, please help me re-organize and tell me how it's like.

+6  A: 

Facebook Connect uses a clever (or insane, depending on your point of view) hack to achieve cross-site communication between your site and Facebook's authentication system from within the browser.

The way it works is as follows:

  1. Your site includes a very simple static HTML file, known as the cross-domain communications channel. This file is called xd_receiver.htm in the FB docs, but it can be named anything you like.
  2. Your site's login page includes a reference to the Javascript library hosted on Facebook's server.
  3. When a user logs in via the "Connect" button, it calls a function in Facebook's JS API which pops up a login dialog. This login box has an invisible iframe in which the cross-domain communications file is loaded.
  4. The user fills out the form and submits it, posting the form to Facebook.
  5. Facebook checks the login. If it's successful, it communicates this to your site. Here's where that cross-domain stuff comes in:
    1. Because of cross-domain security policies, Facebook's login window can not inspect the DOM tree for documents hosted on your server. But the login window can update the src element of any iframe within it, and this is used to communicate with the cross-domain communications file hosted on your page.
    2. When the cross-domain communications file receives a communication indicating that the login was successful, it uses Javascript to set some cookies containing the user's ID and session. Since this file lives on your server, those cookies have your domain and your backend can receive them.
  6. Any further communication in Facebook's direction can be accomplished by inserting another nested iframe in the other iframe -- this second-level iframe lives on Facebook's server instead of yours.

The cookies are secure (in theory) because the data is signed with the secret key that Facebook generated for you when you signed up for the developer program. The JS library uses your public key (the "API key") to validate the cookies.

Theoretically, Facebook's Javascript library handles this all automatically once you've set everything up. In practice, I've found it doesn't always work exactly smoothly.

For a more detailed explanation of the mechanics of cross-domain communication using iframes, see this article from MSDN.

friedo
Thanks friedo.So, my backend has to read the cookies in order to check if the user is authenticated? That's the impression I got form your explanation. If so...then isn't that insecure, because I can STEAL other people's cookies + data inside the cookies...and "create" the cookies myself. Then login to the site? (which then my backened will read the cookies and think that I'm the right user.)
TIMEX
I'm not too familiar with the intricate details of the security model, but I suppose you could capture and spoof their cookies. Those cookies are unique to their account and your app, so you would only be able to use whatever privileges they granted to you anyway, like posting comments to their feed.
friedo
A: 

Please someone correct me if I'm wrong - as I am also trying to figure all this stuff out myself. My understanding with the security of the cookies is that there is also a cookie which is a special signature cookie. This cookie is created by combining the data of the other cookies, adding your application secret that only you and FB know, and the result MD5-Hashed. You can then test this hash server-side, which could not easily be duplicated by a hacker, to make sure the data can be trusted as coming from FB.

A more charming explaination can be found here - scroll about halfway down the page.

scottdoc
A: 

Same issues here, and I think Scott is closer to the solution.

Also Im using "http://developers.facebook.com/docs/?u=facebook.jslib-alpha.FB.init" there open source js framework. So things are a little different.

For me, via the opensource js framework, facebook provides and sets a session on my site with a signature. So what I am thinking is to recreate that signature on my side. - if they both match then the user is who he says he is.

So basically if a user wanted to save something to my database, grab the session signature set up by facebook and recreate that signature with php and validate it against the one facebook gave me?

if($_SESSION['facebookSignature'] == reGeneratedSignature){
   // save to database
}else{
  // go away I don't trust you
}

But how do you regenerate that signature? preferably without making more calls to Facebook?

Derrick