-
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.
-
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/)
-
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.