Created
April 9, 2011 23:23
-
-
Save toretore/911886 to your computer and use it in GitHub Desktop.
Facebook Canvas apps, CSRF protection & session cookies
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Facebook Canvas apps are loaded like this: | |
* User clicks link to app or tab ("page as tab") | |
* An iframe is inserted which loads content from the FB server (NOT yours, yet) | |
Something along the lines of: | |
<iframe src="http://facebook.com/page_proxy.php?appid=123"> | |
* The FB server returns some HTML & JS with an automatically submitting form: | |
<form id="humbaba" target="http://you.com/facebook"> | |
<input type="hidden" name="signed_request"/></form> | |
<script> | |
//signed_request value, etc are inserted into the form | |
$('humbaba').submit(); | |
</script> | |
* Browser (not FB) sends POST request to your app's endpoint URI: | |
POST http://you.com/facebook | |
* Your app responds to this request, and the result is shown in the iframe | |
Apparently, the reasons for doing a POST like this instead of a simple GET (with src="yourapp") is that third-party | |
resources loaded from inside the iframe would get access to the signed request parameter containing user information | |
from the referer header, and (noted with what I perceive as a slightly euphemistic tone) "the only other option was for | |
us to encrypt the UID and that [proved] even more challenging for a great number of devs": | |
http://developers.facebook.com/docs/canvas/post/ | |
PROBLEM | |
The form (obviously) doesn't include the CSRF token, and the session gets reset: | |
https://github.com/rails/rails/blob/v3.0.5/actionpack/lib/action_controller/metal/request_forgery_protection.rb#L97 | |
This can manifest itself in weird ways. Like if your app is accessible outside Facebook and you're logged in, as | |
soon as you open the app from within Facebook you're logged out. | |
SOLUTION | |
Disable CSRF protection for the actions that respond directly to this FB-initiated request. Obviously you | |
should be certain that this is safe before doing so. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#... | |
match 'facebook' => 'whatever#humbaba' | |
#... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class WhateverController < ApplicationController | |
skip_before_filter :verify_authenticity_token, :only => [:humbaba] | |
#Facebook Canvas/Tab endpoint routes to here | |
#POST /facebook | |
def humbaba | |
#Render Facebook content | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
thanks!