Closed Bug 674397 Opened 13 years ago Closed 13 years ago

XMLHttpRequest does not send Cookie: header even when withCredentials = true [CORS]

Categories

(Core :: DOM: Core & HTML, defect)

5 Branch
All
Other
defect
Not set
normal

Tracking

()

RESOLVED INVALID

People

(Reporter: mozilla, Unassigned)

Details

User Agent: Mozilla/5.0 (X11; Linux i686; rv:5.0) Gecko/20100101 Firefox/5.0
Build ID: 20110622232052

Steps to reproduce:

I made a cross-origin XMLHttpRequest GET to a web service that expects a Cookie: header for authentication.  I set withCredentials = true before calling send().


Actual results:

The XMLHttpRequest GET request included the expected Origin: header, but it did not include the Cookie: header.

I verified that Firefox has the cookie by entering the web service URL into the address bar, and seeing the Cookie: header in my http request (shown by wireshark).  Firefox 5.0 sends the cookie for manual page loads, but not for XMLHttpRequest GETs.

I tried it with Firefox 3.6.17, Chromium 12.0.742.112, and Chrome 13.0.782.99 beta.  All of them send the Cookie: header as expected.

Through experimentation, I found that the top two levels of domain name seem to affect whether Firefox 5.0 sends the Cookie: header.  For example, when the ajax GET target is http://api.mydomain.com, requests from origin http://otherhost.mydomain.com include the cookie, but requests from origin http://some.other.domain.com or from http://localhost do not include it.



Expected results:

Firefox should have included the Cookie: header in the request, regardless of the origin domain.  That's why I set withCredentials = true, after all.
Can you provide a test case? Ideally one that connects to your server directly from a bugzilla attachment.

You don't by any chance have any addons installed that affect cookies? Or have you possibly turned off 3rd party cookies in the preferences?
I'm pretty sure withCredentials was implemented in FF6, not FF5.
I did indeed have "accept third-party cookies" disabled.  When I enabled it, Firefox sends the cookie.

This still looks like misbehavior, because the cookie in question is not a third-party cookie.  It was issued by the same site that it is supposed to receive it, using a Set-Cookie header with no domain attribute.
Third-party means "not set by the site whose hostname appears in the url bar".

So if you're doing any cross-site request with third-party cookies disabled, those cookies will by definition not be sent (because the request is cross-site).
Yup, this is how 3rd party cookie blocking works in Firefox in general. (And always have workd, so presumably you don't have 3rd party cookies blocked in your FF3.6 profile).

Blocking these types of cookies is required to prevent tracking, which is what people that turn off 3rd party cookies generally want to do.
Status: UNCONFIRMED → RESOLVED
Closed: 13 years ago
Resolution: --- → INVALID
(In reply to comment #5)
> Third-party means "not set by the site whose hostname appears in the url
> bar".

I'm not sure what you're quoting; that's not a quote from any cookie RFC I'm aware of, but I guess the meaning is about the same as the text in RFC 2965. :)

That RFC also says this:
"N.B.  Mechanisms may be proposed that will automate overriding the third-party restrictions under controlled conditions."
http://tools.ietf.org/html/rfc2965#section-3.3

It seems to me that CORS (along with the withCredentials flag) is exactly such a mechanism.  There is obviously a need for such a thing, as more and more sites rely upon ajax APIs to function properly, and those APIs sometimes live on other sites.  (Witness the increasing popularity of the term "mashup" applied to the web these days.)  That would explain why Chromium/Chrome allows the cookie in CORS requests even when third-party cookies are blocked in the preferences.  I thought that was why Firefox 3.6.17 did the same.

It's also worth reviewing what the current RFC says on the matter:
http://tools.ietf.org/html/rfc6265#section-7.1

So, I guess the question becomes:  how can Firefox move into the modern age of the web and allow cookies for CORS requests, without forcing the user to give up third-party cookie protection on all other requests?  I think the most obvious way is to treat CORS as one of those mechanisms mentioned in the RFC, above.  Another way might be to support third-party cookie blocking on a per-site basis, although that would be quite a bit less user-friendly.
Status: RESOLVED → UNCONFIRMED
Resolution: INVALID → ---
For those who aren't very familiar with CORS, I think it's worth pointing out a couple of things:

Allowing the cookie in the situation I'm describing would not throw open the doors to cross-site tracking cookies.  Remember, We're talking about delivering a cookie to the same domain that set it in the first place, and only to that domain.

Allowing it would also not open up abuse of the target web service.  CORS already protects against this by allowing the communication only for pre-approved origins.  (That's what CORS is for, after all.)
The quote is from me.  It's meant to delimit the definition of "third-party" for Gecko's purposes.

This definition has nothing to do with any RFCs and everything with user tracking, as comment 6 says.

> It seems to me that CORS (along with the withCredentials flag) is exactly such
> a mechanism.

CORS is entirely under the control of the site the request is made to, just like the cookie itself.  The whole point of the third-party cookie preference is to protect the user from that site, so CORS is not an acceptable mechanism for disabling that protection.

> It's also worth reviewing what the current RFC says on the matter:

Yes, it says "do whatever you want with third party cookies".  Very explicitly.

> without forcing the user to give up third-party cookie protection on all
> other requests? 

This is like being slightly pregnant.  Either you're sending third-party cookies for CORS requests and then such requests can be used for cross-site tracking.  Or you're not, and they can't.

A per-site third-party cookie whitelist might be worth looking into.  But that's a separate issue fro the CORS behavior.
Status: UNCONFIRMED → RESOLVED
Closed: 13 years ago13 years ago
Resolution: --- → INVALID
> Remember, We're talking about delivering a cookie to the same domain that set
> it in the first place, and only to that domain.

This is true of all cookies.
Note that if a host has "Access-Control-Allow-Origin:*" and we were to send third-party cookies to that host, then that's no different than just sending third-party cookies to that host even without any CORS involved.
One last note.  You can assume that Jonas is _very_ familiar with CORS.  ;)
(In reply to comment #9)
> > It's also worth reviewing what the current RFC says on the matter:
> 
> Yes, it says "do whatever you want with third party cookies".  Very
> explicitly.

I was referring to the part that reads, "third-party cookie blocking policies are often ineffective at achieving their privacy goals," but you probably guessed as much.

> > without forcing the user to give up third-party cookie protection on all
> > other requests? 
> 
> This is like being slightly pregnant.

No, it isn't, unless you choose to implement it that way.  Maybe I should have specified "legitimate" CORS requests, for clarity.  My point was simply that since these sites exist, more are coming, and people want to use some of them, there ought to be a way for Firefox to help with that rather than obstructing it or losing the otherwise-useful security features that we all love.

> A per-site third-party cookie whitelist might be worth looking into.  But
> that's a separate issue fro the CORS behavior.

Yes, that's exactly what I meant.  Time for a feature request?  Can anyone here think of a better approach?


(In reply to comment #11)
> Note that if a host has "Access-Control-Allow-Origin:*" and we were to send
> third-party cookies to that host, then that's no different than just sending
> third-party cookies to that host even without any CORS involved.

According to the Mozilla developer docs, I don't think that wouldn't work:
"Important note: when responding to a credentialed request,  server must specify a domain, and cannot use wild carding."
https://developer.mozilla.org/en/HTTP_access_control#Requests_with_credentials


(In reply to comment #12)
> One last note.  You can assume that Jonas is _very_ familiar with CORS.  ;)

Heh. Fair enough.  :)
Following up on web browser behavior, for the record...

(In reply to comment #6)
> presumably you don't have 3rd party cookies blocked in your FF3.6 profile).

Yep; Turns out that was the case.

(In reply to comment #7)
> That would explain why
> Chromium/Chrome allows the cookie in CORS requests even when third-party
> cookies are blocked in the preferences.

I just tried Safari, Mobile Safari, and Midori, and they send the cookie as well.  Perhaps it's a WebKit thing.
(In reply to comment #13)
> According to the Mozilla developer docs, I don't think that wouldn't work:

Oops.  That should have been "I don't think that would work"
Anyone is always free to open a feature-request bug :)

However do remember that people that turn off 3rd party cookies do so with the intent of preventing tracking. So any feature which turns cookies back on in such a way that it allows tracking even when 3rd party cookies are turned off is likely not going to be implemented.

Also remember that tracking usually involves both the website that the user is visiting, and the website that is being requested, cooperating with the intent of wanting to track the user. So it's easy for them to set .withCredentials to true and have the server respond with the appropriate CORS headers.
Thanks, all, for discussing rather than simply dismissing.

I'll ponder a solution that doesn't allow a tracking exploit.  If only there was a reliable way to distinguish a login cookie from a tracking cookie, I think this would be easier.  Maybe a whitelist really is the only way.
Hi Everybody.
Years later, I'm having exactly same issue. I'm using Firefox developer edition 62.0b11 (64-bit) and I have enabled third party cookies as well. Tested on Chrome, IE, Edge and everything works.
Can someone help me with this situation?
Please file a new bug with steps to reproduce (e.g. the URL of the page where you are seeing the problem).  Ideally, attach logs created per https://developer.mozilla.org/en-US/docs/Mozilla/Debugging/HTTP_logging with "cookie:5" added to the list of modules to log.  Please cc me on the bug and I will try to get it directed to the right place.
Sorry, I can't give you such information because.
you can read actual bug here : https://stackoverflow.com/questions/49591535/firefox-does-not-keep-cookies-sent-by-cross-domain-even-with-all-cors-allow
That doesn't have enough information (e.g. about browser settings, actual HTTP requests and responses, etc) to be actionable.  Most simply, it's missing the value of the Set-Cookie header and the actual hostnames involved.  This stuff matters.

Again, if you either have a way for a developer to reproduce the problem or can create a log showing it, please file a bug with the relevant information.
Component: DOM → DOM: Core & HTML

Reproduction on a live environment: jabcreations.com

This bug is Gecko specific and after a system initiation the cod window.location.reload(true); is executed. With or without the first parameter it does NOT send the cookie and thus the server generates a new cookie. This creates a looping effect on my server until the system outright rejects the browser with a generic error.

From a brief review of my logs it is effecting two thirds of all people using Gecko browsers. I'm not sure how to attach the cookie to the request though I could attempt to create a JavaScript request and force the cookie to be sent some how.

As far as I'm concerned any bug that prevents two thirds of an entire rendering engine to fail to load one of the most basic commands (location.reload()) is a severe bug.

Apparently window.location.href = window.location.href; works fine and I've updated my system. I'll watch the domain accounts I control to see if this resolves the issue. If a test case is desired I will be happy to create one.

Keep in mind that all my software is first-party and that there was zero third party requests or software of any kind while this bug was being triggered, this is NOT an issue with third party cookies - unless there is a separate issue with those cookies being set.

John, please see comment 21. This bug is marked invalid; commenting here is not really that useful. If you think you are encountering a bug, please file that bug, with steps to reproduce or something else that would enable someone to make progress on it...

You need to log in before you can comment on or make changes to this bug.