Cross-Site Browser Cookie Setting
April 14th, 2007 by Ralf S. EngelschallLet me share some experiences of this week. Perhaps it is of interest to someone who has solve a similar problem…
Suppose your organization runs three websites: www.example.com (your corporation), www.example.net (your community network) and www.example.org (your open source project). And under www.example.com/login.cgi you have the login page for your fellows. Once the customer is authenticated there, an authorization cookie containing an issued “certificate” should be set in the browser. This certificate in turn will be checked by all web pages under www.example.com, www.example.net and www.example.org to to determine whether the user is access granted or not.
Setting the authorization cookie for the domain “.example.com” from www.example.com/login.cgi is trivial, of course. You just send the cookie in the HTTP response and that’s it. But how do you set the same cookie also for the two sibling domains “.example.net” and “.example.org“? Because of the “same origin policy” enforced by all browsers, if you just return the two additional cookies also in the HTTP response of www.example.com/login.cgi they will be silently ignored by the browser. So what to do?
The the solution simply is that only a HTTP response from somewhere under www.example.net can set the cookie for “.example.net” and a HTTP response from somewhere under www.example.org can set the cookie for “.example.org“. But remains the important question: how can we automatically and unobtrusively load something from www.example.net and www.example.org in the response from www.example.com/login.cgi?
The key here is Cross-Site AJAX, as abstracted in my new jQuery plugin jquery.xsajax.js. Short recap: in JavaScript one dynamically generate a <script> DOM element with a type attribute set to text/javascript and a src attribute set to the URL of the foreign URL. But how is this of help here?
Well, in JavaScript we load on the displayed page of www.example.com/login.cgi the two foreign URLs www.example.net/reflector.cgi and www.example.org/reflector.cgi. Behind those two CGIs is nothing more than a simple “certificate” reflector, i.e., it expects the “certificate” in the query string and returns it as a cookie in the HTTP response header. For things like embedded images it doesn’t work, but for scripts all known browsers accept to set cookies!
The content of the two CGIs has to be of type text/javascript but can be just empty. Only the cookie in the HTTP response is what we are interested in. And because the cookie is now set for the “same origin” by the two reflector CGIs, we result in the “certificate” set in three cookies: one set directly with the HTTP response of www.example.com/login.cgi and two set indirectly with the HTTP response of www.example.net/reflector.cgi and ww.example.org/reflector.cgi through the asynchronously loaded scripts in the background. You got the trick? Voila!
PS: I have to confess that some small problem remains. For MSIE one small cruel trick is necessary: the reflector CGIs have to send a P3P header which contains some necessary bits (which particular one I intentionally leave as an exercise to the reader ;-) to force MSIE into also accepting the cookie

![Ralf S. Engelschall's Train of Thoughts [.org]](http://trainofthoughts.org/blog/wp-content/themes/tot/tot-img/tot-2-CUT-typo-T.png)
April 18th, 2007 at 20:16 |
With P3P headers, IE allows setting cookies from a domain rather than the domain of the document being browsed (I mean “3rd party cookie”). But Safari blocks all 3rd party cookies even if the P3P bits are present in the header. However, Safari sends 3rd party cookies.
To allow cross domain cookies setting in Safari, the only way seems to be window.open. Is there a better way?
May 31st, 2007 at 20:19 |
I really enjoyed your articles on phishing and other things like java script I would like to know if i can get some articles from you and be a mail recipient from your mail desk.
June 22nd, 2007 at 2:00 |
I ran into the same problem, though my solution involved iframes. I also had to send the compact privacy policy header. It seems to be working fine but I must confess I haven’t tested Safari yet, I’ll have to check that out asap.
November 20th, 2007 at 14:07 |
I had an issue with Safari. I implemented the P3P headers to make sure IE worked (I used iframes) and this was doing fine… Unfortunately, users with Safari arfe not that fortunate. Safari just won’t accept cross-domain cookies combined with Iframes. Too bad…
July 13th, 2009 at 13:27 |
Hey,
It was a great article. But, I am exactly facing the same issue as you have mentioned in your last para, about forcing IE to accept cookies. Could you suggest a solution for same?
July 13th, 2009 at 18:29 |
Nikhil: as I mentioned, the solution is to send a P3P HTTP header.