Can jQuery.getJSON put a domain's cookies in the header of the request it makes?
Asked Answered
I

2

3

(Note: See also the related question Can browsers react to Set-Cookie specified in headers in an XSS jquery.getJSON() request?)

I can't seem to set a cookie (whose name is mwLastWriteTime) in the request header of a JSON operation. The request itself is a simple one from the Freebase MQL tutorials, and it is working fine otherwise:

// Invoke mqlread and call the function below when it is done.
// Adding callback=? to the URL makes jQuery do JSONP instead of XHR.
jQuery.getJSON("http://api.sandbox-freebase.com/api/service/mqlread?callback=?",
{query: JSON.stringify(envelope)},   // URL parameters
displayResults);                     // Callback function

I'd hoped that I could set this cookie with something along the lines of:

$.cookie('mwLastWriteTime', value, {domain: ".sandbox-freebase.com"});

Unfortunately, looking in FireBug at the outgoing request header I see only:

Host    api.sandbox-freebase.com
User-Agent  [...]
Accept  */*
Accept-Language en-us,en;q=0.5
Accept-Encoding gzip,deflate
Accept-Charset  ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive  115
Connection  keep-alive
Referer [...]

But if I don't specify the domain (or if I explicitly specify the domain of the requesting site) I can get mwLastWriteTime to show up in the headers for local requests. Since the .sandbox-freebase.com domain owns these cookies, shouldn't they be traveling along with the GET? Or does one need a workaround of some sort?

My code is all JavaScript, and I would like to set this cookie and then call the getJSON immediately afterward.

Inter answered 24/11, 2010 at 1:11 Comment(0)
A
5

You cannot set a cross-domain cookie, because that would open the browser (and therefore the user) to XSS attacks.

To quote from the QuirksMode.org article that I reference above:

Please note that the purpose of the domain is to allow cookies to cross sub-domains. My cookie will not be read by search.quirksmode.org because its domain is www.quirksmode.org . When I set the domain to quirksmode.org, the search sub-domain may also read the cookie. I cannot set the cookie domain to a domain I'm not in, I cannot make the domain www.microsoft.com . Only quirksmode.org is allowed, in this case.

If you want to make cross-site request with cookie values you will need to set up a special proxy on a server you control that will let you pass in values to be sent as cookie values (probably via POST parameters). You'll also want to make sure that you properly secure it, lest your proxy become the means by which someone else's private information is "liberated".

Angie answered 24/11, 2010 at 1:23 Comment(6)
The server's reply, however, can definitely set a cookie. IMO, this is just something that shouldn't be done in js, anyways.Additional
I wonder why there are so many API docs which fail to mention this, and instead say things like "Using the options object, cookies can be set with several options such as the domain and or path for which the cookie should be available, expiration date for the cookie, and whether the cookie should be sent over HTTPS only."! code.google.com/p/cookies/wiki/DocumentationInter
@Hostile Fork -- sometimes it's because the writer assumed knowledge of XSS limitations, and sometimes it's because the writer doesn't know. I'd wager the former in this case.Angie
But... is there no way to use JavaScript to modify the outgoing request header to give it a cookie value for the duration of a request, without actually reading or writing the browser's cookie database?Inter
@Hostile Fork -- JavaScript doesn't actually modify the request headers when you set a cookie at all -- and it actually doesn't have any access to the headers that are emitted by the browser when requesting a url that is not in the same domain. If you're on the same domain, the XHR object does have a setRequestHeader method that can be used to set headers (and this may let you update cookies with JavaScript on domains that don't violate the Same-Origin policy.) en.wikipedia.org/wiki/…Angie
Ah, drat. Well this really seems like a case where having this parameter as a cookie should be something you can override by putting it in a parameter of the payload (or perhaps in the URL). I'll ask Freebase about it, and try working around it some other way in the meantime... thanks...Inter
T
0

Are you running all of your tests through localhost? Are you using IE? If so it will be enforcing its own special brand of security requirements and likely dumping your cookies. Open fiddler and use http://ipv4.fiddler to bypass that.

If that type of trickery is not going on (as it appears you are using FireFox) , it may also be the case that you do need to explicitely set the cookie's domain to be the same as the domain of your JSON request. A browser won't send cookies set for domain A to a request to domain B. I am not 100% sure this is the case though.

Tonguelashing answered 24/11, 2010 at 1:22 Comment(2)
My script is "live" on a .com domain, which is making the request of api.sandbox-freebase.com. Explicitly setting the domain to the one the script is running on will get it to pass the cookie along to local requests, but not to sandbox-freebase. And explicitly setting the domain to sandbox-freebase does not make the cookie appear anywhere (it is invisible to the Firebug debugger on my domain, presumably because it does not have the privileges to read it after it has written...?)Inter
They've got you covered down below.Tonguelashing

© 2022 - 2024 — McMap. All rights reserved.