How does Facebook set cross-domain cookies for iFrames on canvas pages?

61,306

So the iFrame isn't actually setting the u cookie for the runwithfriends.appspot.com domain. What Facebook does is it creates a form, <form action="runwithfriends.appspot.com/..." target="name_of_iframe" method="POST"> and uses javascript to submit the form on page load. Since the form's target is the iframe, it doesn't reload the page... it just loads the iframe with the POST's response. Apparently even Chrome and other browsers with strict cookie policies set cookies for cross domain requests if they are POST requests...

Share:
61,306

Related videos on Youtube

Aaron Gibralter
Author by

Aaron Gibralter

Updated on July 05, 2022

Comments

  • Aaron Gibralter
    Aaron Gibralter almost 2 years

    I was browsing Facebook's documentation reading about canvas applications and I came across an example application: http://developers.facebook.com/docs/samples/canvas. As I read through their example, however, I got very confused about their use of cookies in the iframe application.

    A little backstory...

    I had already played around with using iframes for embeddable widgets (unrelated to Facebook) and I found out a few browsers (Chrome, Safari, etc.) have strict cookie policies and don't allow cross-domain cookies set in iframes (Firefox, on the other hand, allows iframes to set cross-domain cookies in iframes). For example, if foo.com has an iframe with src="http://bar.com/widget" the iframe widget will not be able to set any cookies for bar.com and therefore will have trouble persisting state within the iframe: bar.com will interpret every request (including ajax requests) from the widget as a fresh request without an established session. I struggled, and found a way around this by using JSONP and javascript to set cookies for foo.com instead...

    ... and so?

    Well, I was looking at the example canvas iframe Facebook application and I noticed that their application (hosted on runwithfriends.appspot.com) is able to set a cookie, u, with the current user's id along with a few other parameters for the runwithfriends.appspot.com domain. It sends this cookie with every request... and it works in both Chrome and Firefox! WTF? How does Facebook get around the cross-domain cookie restrictions on Chrome?

    (I already know the answer now, but I thought this might be helpful for anyone struggling to figure out the same thing -- I'll post the answer below.)

    • Aaron Gibralter
      Aaron Gibralter almost 11 years
      Update: the latest versions of some browsers (Safari v6.x+ on OS X, Safari on iOS 6+, and I assume Chrome and FF soon) do not allow for setting of cross-domain cookies anymore, even on post-to-iframe requests.
  • Aaron Gibralter
    Aaron Gibralter over 13 years
    I created a proof of concept sinatra app to demonstrate how this works: github.com/agibralter/iframe-widget-test
  • lshettyl
    lshettyl almost 13 years
    Hey Aaron, Do you have a pure Javascript version of this code/demo please?
  • Aaron Gibralter
    Aaron Gibralter almost 13 years
    @LShetty -- sorry, I'm not sure I understand what you mean... pure Javascript? The Ruby portion of the demo acts as the web server... do you mean you want to see the demo written in Node.js?
  • Francesco
    Francesco over 12 years
    I has same hard time LShetty had. I don't get what your code is for. what about a php solution, i don't get form your code where's the beef..
  • Aaron Gibralter
    Aaron Gibralter almost 11 years
    @Seth I haven't checked in a while, but the latest version of Safari (v6.0/iOS6 and I assume soon Chrome and FF) don't allow this trick anymore: the cookies don't get set on post-to-iframe requests. I'd have to look into how Facebook is handling this for new browsers. For now, localStorage seems like a good alternative method.
  • Serge Kvashnin
    Serge Kvashnin over 9 years
    Here is a little post about it nfriedly.com/techblog/2010/08/…
  • Miguel
    Miguel almost 8 years
    Let me just tell you, that if you have "disable third party cookies" that workaround iframe thing will stop working i believe.
  • Aaron Gibralter
    Aaron Gibralter almost 8 years
    A lot has changed in the last 5 years... :)
  • comte
    comte over 7 years
    today, with Chrome (Chromium 51 on linux): with cookies set with domain B, then try to read from an iframe (domain B) within parent page (domain A) : impossible*. localStorage() with script in iframe (domain B) : impossible*, you have an "acced denied" error message. * means impossible except if user doesn't uncheck "Block third party..." in settings/content. if you uncheck both work but don't count on users to uncheck...
  • naviram
    naviram almost 7 years
    So is there a way to set 3rd party cookie today, when it is set in browser to block 3rd party cookie? Or is can someone verify that it is not possible today in any way?
  • caw
    caw over 5 years
    @naviram It is not possible, as that is exactly what the relevant browser setting is for. If it was possible, that would be a security bug in the affected browsers and would certainly be fixed soon after.
  • Aaron Gibralter
    Aaron Gibralter over 5 years
    @caw it certainly was possible as I used that loophole for an embeddable polling application from 2009-2013, and it worked in all browsers with default settings. It was not treated as a security bug for some reason as it was left open for a very, very long time.
  • caw
    caw over 5 years
    @AaronGibralter I definitely don’t doubt that. But browsers’ security policies do change, and 5-9 years is a long time in the development of web browsers. Today, if you opt to block third-party cookies, that usually works reliably.
  • Aaron Gibralter
    Aaron Gibralter over 5 years
    @caw true true.
  • hsuk
    hsuk over 4 years
    lol, these comments actually do explain a lot about the evolution of web browser cookies over time ...
  • diegoddox
    diegoddox about 4 years
    I'm trying to see how facebook cookies httponly are been set today but when debugging the network request I can see some request but there is not set-cookie on the headers, any idea how this is happening? @AaronGibralter
  • Aaron Gibralter
    Aaron Gibralter about 4 years
    Honestly, I haven't looked at how this works with modern browsers...
  • Zbyszek
    Zbyszek over 3 years
    Third-party cookies will be phased out totally in the next 1.5 - 2 years, at least in Chrome, Safari, and most probably Firefox. They were already phased out on the newest versions of Safari and from the incognito mode of Chrome. Users can also turn them off. The current workaround for the browsers where it still works is to check if cookies are saveable from an iframe and if not - shortly open iframe domain in main window (redirect to url and back by JS). Then with proper parameter SameSite (for example SameSite=None) in the cookie they work, but only in those browsers.
  • Luminous
    Luminous over 2 years
    Sounds like me trying to figure out how to pass microsoft's b2c session cookie across subdomains via iframe is a solution that's very limited now.