Closed Bug 1627653 Opened 4 years ago Closed 4 years ago

SameSite strict cookies cannot be read from JavaScript

Categories

(Core :: Networking: Cookies, defect, P2)

74 Branch
defect

Tracking

()

RESOLVED FIXED
mozilla77
Tracking Status
firefox77 --- fixed

People

(Reporter: janiskoehr, Assigned: baku)

References

Details

(Whiteboard: [necko-triaged], [wptsync upstream])

Attachments

(4 files)

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0

Steps to reproduce:

If I set a cookie via JavaScript like so (on a site browsed with https of course):

document.cookie = "FOO=bar; SameSite=Strict; Secure";

I want to read that cookie again later in time by calling:

var cookies = document.cookie;

I've made a small proof on github pages:
https://janis91.github.io/firefox-samesite-cookie-proof/

Actual results:

The cookie is not part of the returned string (empty string in this case).

Expected results:

The cookie string should be returned ("FOO=bar"), because it is not a httpOnly cookie and it is accessed by the same site. On Chrome and IE or Edge the behavior is like expected and I can access/retrieve the cookie.

(In reply to janiskoehr from comment #0)

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0

Steps to reproduce:

If I set a cookie via JavaScript like so (on a site browsed with https of course):

document.cookie = "FOO=bar; SameSite=Strict; Secure";

I want to read that cookie again later in time by calling:

var cookies = document.cookie;

I've made a small proof on github pages:
https://janis91.github.io/firefox-samesite-cookie-proof/

Actual results:

The cookie is not part of the returned string (empty string in this case).

Expected results:

The cookie string should be returned ("FOO=bar"), because it is not a httpOnly cookie and it is accessed by the same site. On Chrome and IE or Edge the behavior is like expected and I can access/retrieve the cookie.

I have a small adjustment:
Seems like this is only true, given the cookie wasn't present before page load. So I added a Max-Age=3 to the cookie. Moreover, the problem appears to be only existing when navigating to the site via link or similar. When I open a new plain tab and paste the url, then it works.

In my original scenario I am creating a XSRF-TOKEN cookie directly before an ajax POST request. The request then reads the value and puts it to an additional header "X-XSRF-TOKEN". In order to avoid XSRF attacks. The problem is, that when trying to read the cookie in this case, the cookie is not returned (on localhost). I can only reproduce this behavior on other domains (like github.io) when clicking a link and not via opening the url manually (weird, I know).

the cookie is not returned (on localhost). I can only reproduce this behavior on other domains (like github.io)

It is exactly what SameSite=Strict cookie should block. If it is the problem, you should not use SameSite=Strict.

(In reply to Masatoshi Kimura [:emk] from comment #2)

It is exactly what SameSite=Strict cookie should block. If it is the problem, you should not use SameSite=Strict.

I must hardly disagree. On MDN the SameSite cookie description says for "Strict":

The browser will only send cookies for same-site requests (requests originating from the site that set the cookie). If the request originated from a different URL than the URL of the current location, none of the cookies tagged with the Strict attribute will be included.

So Strict means, that if a cookie with this setting exists for a site, let's name it foo.com, a click on a link from bar.com to foo.com will not send this cookie. With Lax the browser would send the cookie whne clicking on this link. Moreover cross-site requests like XHR or so-called ajax requests from bar.com to foo.com don't hold this cookie.
But the scenario I describe begins after the site foo.com is fully loaded, when previously clicked on the link to foo.com on bar.com. If after that a JavaScript snippet creates a cookie with SameSite=Strict on foo.com itself and attempts to read it at a later point in time on the same site over "document.cookie", the script has no access. Although it is the Same Site and there is no XSRF risk at this point (which is the reason SameSite was introduced). This is NOT what SameSite=Strict should block.
It appears to me that even when getting redirected from another site (like for example after Open ID Connect Login), this behavior applies.

SameSite=Strict means to me, that browsers do not send cookies with the GET request initiated by the link and in addition do not send them with any cross-site requests. But in the described scenario neither of the two is the case. The script that accesses and creates the cookie is originated from the same site.

Component: Untriaged → Networking: Cookies
Product: Firefox → Core

Ehsan, what do you think? Sounds like notabug but just wanted to double check since reporter says it works on Chrome.

Flags: needinfo?(ehsan)

(In reply to Andy Grover [:grover] from comment #4)

Ehsan, what do you think? Sounds like notabug but just wanted to double check since reporter says it works on Chrome.

Could you please explain why this is not a bug to you? Maybe I don't understand what the SameSite directive is about but why should a page be able to create a SameSite=Strict cookie and then not allowed to read it afterwards? And that only, because the visitor of the page has been redirected or navigated by clicking a link instead of opening the page directly. I can't understand why this is considered expected behavior.

I may misunderstand the MDN and Standard documents, don't get me wrong. But perhaps it is possible to explain this to me. Everyone I talked about that scenario considers this a bug. At least after looking at my proof. I only created that proof to be able to reproduce it with a few clicks.

The core question for me is: Why should a page like mine not be allowed to create and read its own cookie with JavaScript and secure it as good as possible (SameSite=Strict) only because a visitor has been following a link to that page instead of opening the page directly?

This makes no sense to me and does not align to the documentation on MDN.

Maybe I get the whole thing wrong and the SameSite=Strict cookie should not be created at all from JavaScript, but even then there is something wrong, because it is possible, you just can't read it in described situations.

janiskoehr is right. The spec says:

https://html.spec.whatwg.org/#dom-document-cookie

The cookie attribute represents the cookies of the resource identified by the document's URL. [...]
On getting, if the document is a cookie-averse Document object, then the user agent must return the empty string. Otherwise, if the Document's origin is an opaque origin, the user agent must throw a "SecurityError" DOMException. Otherwise, the user agent must return the cookie-string for the document's URL for a "non-HTTP" API, decoded using UTF-8 decode without BOM. [COOKIES]"

No same-site strict should not be applied to document.cookie. I take this bug.

Assignee: nobody → amarchesini
Flags: needinfo?(ehsan)
Priority: -- → P2
Whiteboard: [necko-triaged]
Attachment #9140400 - Attachment description: Bug 1627653 - document.cookie should expose all the cookies, ignoring sameSite limitations, r?ckerschb → Bug 1627653 - document.cookie should expose all the cookies, ignoring sameSite limitations - part 1 - implementation, r?ckerschb
Attachment #9140401 - Attachment description: Bug 1627653 - Extra cleanup in CookieServiceChild, r?ckerschb → Bug 1627653 - document.cookie should expose all the cookies, ignoring sameSite limitations - part 2 - extra cleanup in CookieServiceChild, r?ckerschb
Attachment #9140758 - Attachment description: Bug 1627653 - Fix document.cookie + sameSite tests, r?ckerschb → Bug 1627653 - document.cookie should expose all the cookies, ignoring sameSite limitations - part 3 - fix tests, r?ckerschb
Attachment #9140961 - Attachment description: Bug 1627653 - Add WPTs for document.cookie, r?ckerschb → Bug 1627653 - document.cookie should expose all the cookies, ignoring sameSite limitations - part 4 - WPTs, r?ckerschb
Pushed by amarchesini@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/9bd94e187037
document.cookie should expose all the cookies, ignoring sameSite limitations - part 1 - implementation, r=ckerschb,mgoodwin,necko-reviewers,valentin
https://hg.mozilla.org/integration/autoland/rev/ab9fb26ff535
document.cookie should expose all the cookies, ignoring sameSite limitations - part 2 - extra cleanup in CookieServiceChild, r=ckerschb,necko-reviewers,valentin
https://hg.mozilla.org/integration/autoland/rev/b9f059860fcc
document.cookie should expose all the cookies, ignoring sameSite limitations - part 3 - fix tests, r=ckerschb
https://hg.mozilla.org/integration/autoland/rev/41a6cf4e5128
document.cookie should expose all the cookies, ignoring sameSite limitations - part 4 - WPTs, r=ckerschb,annevk
Created web-platform-tests PR https://github.com/web-platform-tests/wpt/pull/23113 for changes under testing/web-platform/tests
Whiteboard: [necko-triaged] → [necko-triaged], [wptsync upstream]
Upstream web-platform-tests status checks passed, PR will merge once commit reaches central.
Upstream PR merged by moz-wptsync-bot
Regressions: 1642832
See Also: → 1641459
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: