How do cookies work with domains, paths and overriding? - http

I have been reading through How do browser cookie domains work? and the RFC at and it answered many of my questions about cookies. Not all of them though (though I'm sure the answer is in the RFC, I haven't been able to properly parse it). I have some more questions, which I will pose in the same format as the above question.
should a cookie for www.example.com be available to www.example.com/path?
should a cookie for example.com/path be available for www.example.com?
should www.example.com be able to set a cookie for www.example.com/path?
should a cookie for www.example.com/path be available to www.example.com?
should www.example.com/path be able to set a cookie for www.example.com?
if a cookie is set for www.example.com containing foo=bar, and after that a cookie is set for example.com containing foo=baz should example.com be sent the former, or the latter or both?
if a cookie is set for www.example.com containing foo=bar that expires in a day, then a cookie containing foo=baz is set that will expire in 15 minutes, should after the latter cookie expires the former cookie be sent?
EDIT One more:
if a cookie is set for www.example.com containing foo=bar, and after that a cookie is set for example.com containing foo=baz what cookie should www.example.com be sent?
Also fixed second case

should a cookie for www.example.com be available to www.example.com/path?
Yes
should a cookie for example.com/path be available for www.example.com?
No
should www.example.com be able to set a cookie for www.example.com/path?
(Yes) Most likely (Cookie Path is not a security feature)
should a cookie for www.example.com/path be available to www.example.com?
(No) The cookie will not be sent to www.example.com, but www.example.com can contain javascript that can fetch the cookie through an iframe. Again, cookie path is not a security feature.
should www.example.com/path be able to set a cookie for www.example.com?
Yes
if a cookie is set for www.example.com containing foo=bar, and after that a cookie is set for example.com containing foo=baz should example.com be sent the former, or the latter or both?
Latter, because example.com does not have access to www.example.com's cookies.
if a cookie is set for www.example.com containing foo=bar that expires in a day, then a cookie containing foo=baz is set that will expire in 15 minutes, should after the latter cookie expires the former cookie be sent?
No, because the second cookie will overwrite the first.
if a cookie is set for www.example.com containing foo=bar, and after that a cookie is set for example.com containing foo=baz what cookie should www.example.com be sent?
Unspecified behaviour. Either or both (concatenated) seems to be valid.
How to handle multiple cookies with the same name
Edit: Added answer to new question, corrected question 2 and changed answer.

Related

Can the 'Domain' of set-cookie valued any domain?

Can the 'Domain' of set-cookie valued any domain?
eg:
when login www.google.com,
a xhr to facebook.com is requested
and responsed with a response Header set-cookie:aaa=1;domain=twitter.com.
Will the cookie be set to domain=twitter.com successfully?
No. It cannot. HTTP clients, user-agents and web browsers are required to reject any Set-Cookie header that specifies a Domain= that does not match the Origin of the current document.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie
A cookie for a domain that does not include the server that set it should be rejected by the user agent.
The following cookie will be rejected if set by a server hosted on originalcompany.com:
Set-Cookie: qwerty=219ffwef9w0f; Domain=somecompany.co.uk
A cookie for a sub domain of the serving domain will be rejected.
The following cookie will be rejected if set by a server hosted on example.com:
Set-Cookie: sessionId=e8bb43229de9; Domain=foo.example.com
The Set-Cookie header's Domain= parameter is to allow a subdomain's website to allow its cookies to be used by a parent domain website, but not the other way around.
Note that browsers are aware of the structure of ccTLDs, so a website at example.co.uk cannot use Set-Cookie, Domain=co.uk, but a website at subdomain.example.co.uk can use Set-Cookie, Domain=example.co.uk.

Are my cookies really HTTP only? Flag is absent in Cookie request header

Ive made some configurations to (finally) have my cookies set on HTTP only.
"Seem" to work.
Ive tried them with postman and I have the following:
When I hit the login page:
On the cookies section, my cookie with name JSESSIONID appears to be HTTP only (it has the check)
When I enter to the logged area , the same result...
The headers dont give me more details.
Then,
I check it with google chrome. I open the developers toolbar.
I load the login page.
At the headers on the response headers I get
Set-Cookie: JSESSIONID=434434..... HttpOnly
So, its fine (I guess).
Then I reload the page (or sign in).
Then the problem:
No response headers received.
The Request Headers brings my cookie (with the same ID at then the previous one) without the httponly, host info or any other cookie value I set before.
At the cookies tab I get Request Cookies only and no Response cookie.
And the request cookie is non http-only
At my resources tab, the Cookie is there, as HTTP only and with the previous values I set.
My question now is... Is it a really http-only cookie? Or my configuration is not properly set?
Should I always get the response cookie or the request cookie should be always http-only (In case I am trying to set it as http-only) or is this behavior normal (or at least accepted) ?
When I try to print my cookie with Javascript at both scenarios I get a null as response (what makes me think then it is correct).
Ideas?
Client doesn't send cookie attributes other than name and value back to server.
See also RFC6265 section 4.2.2 (emphasis mine).
4.2.2. Semantics
Each cookie-pair represents a cookie stored by the user agent. The
cookie-pair contains the cookie-name and cookie-value the user agent
received in the Set-Cookie header.
Notice that the cookie attributes are not returned. In particular,
the server cannot determine from the Cookie header alone when a
cookie will expire, for which hosts the cookie is valid, for which
paths the cookie is valid, or whether the cookie was set with the
Secure or HttpOnly attributes.
Everything's behaving as specified.

Cookie is not deleted by HTTP header

My project is using an external authentication provider that sets a cookie if a user is logged in. To log out, I have to delete that cookie.
As far as I can tell, the Set-Cookie header is correct, but the cookie isn't changed.
This is the header:
{{cookie_name}}: ""
domain: "{{cookie_domain}}"
expires: "1970-01-01T00:00:00.000Z"
path: "/"
This is the cookie before, and after, going to the logout view:
Name: {{cookie_name}}
Content: (random string to verify login)
Host: {{cookie_domain}}
Path: /
Send for: Encrypted connections only
Expires: At end of session
Everything is HTTPS. Does anyone know of reasons that a Set-Cookie header might not work?
Did you try setting all the attributes in the Set-Cookie header when you try to delete the cookie. All attributes that are set in the exisiting cookie should be set when you try to delete.
From the example you gave above, it seems you are not setting the secure flag when you try to delete the cookie.
It was really an issue with the framework I use (Django). When I manually set the domain in the set_cookie function, it prefixed a period which meant that it didn't match the existing cookie. When I didn't enter a domain, it used the default and didn't prefix anything, and it worked.

Should a cookie with the host-only-flag replace a cookie without it?

RFC 6265 states that a user-agent should proceed in the following way when receiving a Set-Cookie header:
If the Domain attribute is set:
Set the cookie's domain to the domain-attribute.
Set the cookie's host-only-flag to false.
If the Domain attribute is not set:
Set the cookie's domain to the canonicalized request-host.
Set the cookie's host-only-flag to true.
This is all clear. The confusion comes with this paragraph:
If the user agent receives a new cookie with the same cookie-name,
domain-value, and path-value as a cookie that it has already stored,
the existing cookie is evicted and replaced with the new cookie.
Let's take an example, with two cookies received on the domain www.example.com:
Set-cookie: name=value
Set-Cookie: name=value; Domain=www.example.com
The domain (and path) will be the same for both cookies, but the first one will have the host-only-flag set to true, and the second one to false.
Reading the RFC, it looks like it doesn't matter when comparing the two cookies, and they should be considered equivalent anyway, but I'm not sure my interpretation is correct.
Should the user-agent replace the first cookie with the second one, or should it store both of them?
The paragraph that confuses you is about the ability to assign a new value to a cookie (as well as changing/refreshing the cookie expiration date). If it were not written that way, the HTTP client would need to store multiple cookies with the same name could and it would need to decide on another criterium which to send to the HTTP server upon the next request.
Regarding the second part of your question:
If those two cookies are specified within the same request, the second one "wins", therefore a cookie with the host-only-flag = false would be stored.
If those two cookies come in separate requests, the second one overwrites the first one, because they match in cookie-name (specified), domain-value (once specified, once derived), and path-value (derived). When storing them, the entries in the browser's cookie database only differ in the host-only-flag.
This host-only-flag comes into effect when the client issues a new request to the server (snippet from RFC6265):
The user agent MUST use an algorithm equivalent to the following
algorithm to compute the "cookie-string" from a cookie store and a
request-uri:
1. Let cookie-list be the set of cookies from the cookie store that
meets all of the following requirements:
* Either:
The cookie's host-only-flag is true and the canonicalized
request-host is identical to the cookie's domain.
Or:
The cookie's host-only-flag is false and the canonicalized
request-host domain-matches the cookie's domain.
The fine detail is in how the domain is compared. The matching algorithm is specified in section 5.1.3.
Essentially you can have a cookie be valid for all subdomains if the domain is specified with a leading "."
When the domain is omitted, though, (and therefore implied by the server from the request), this can never be the case because there always needs to be an identical match in the domain.
Further research determined:
In practice browsers store a domain that has been specified in the cookie with a prepended . (for www.example.com it will store .www.example.com) so that a request to subdomain.www.example.com will also return that cookie. When no domain is specified the plain domain without a prepended . will be stored, thus a request to a subdomain will not include that cookie.

Domain set cookie for subdomain

I looked in many questions about cookies but I didn't find an answer on my problem. I have following scenario:
A user creates a login on example.com and should get a cookie but only for the subdomain fuu.example.com. I generate following HTTP header part:
Set-Cookie: name=TestUser; Domain=fuu.example.com; Path=/; secure; HttpOnly
But when I make a request to https://fuu.example.com, the cookie will be not added to the request. I wonder if it is possible that example.com sets a cookie for fuu.example.com. I know that it is possible that example.com set a cookie for .example.com also for all subdomains for example.com but that's not what I want.
How do I set a cookie for a subdomain? I am not seeing the cookie in a request to the subdomain.
No. Besides that fuu.example.com is an invalid Domain value (it must start with a ., i.e. .fuu.example.com) (see update below) the cookie would get rejected:
To prevent possible security or privacy violations, a user agent rejects a cookie (shall not store its information) if any of the following is true:
The request-host is a Fully-Qualifed Domain Name (not IP address) and has the form HD, where D is the value of the Domain attribute, and H is a string that contains one or more dots.
The request-host is example.com and the Domain attribute value is foo.example.com. But the request-host example.com does not has the form HD where D would be foo.example.com. Thus the cookie gets rejected.
Update    The current specification RFC 6265, that obsoleted RFC 2109 that is quoted above, does ignore the leading dot. But the effective domain is handled the same:
[…] if the value of the Domain attribute is
"example.com", the user agent will include the cookie in the Cookie
header when making HTTP requests to example.com, www.example.com, and
www.corp.example.com. (Note that a leading %x2E ("."), if present,
is ignored even though that character is not permitted, but a
trailing %x2E ("."), if present, will cause the user agent to ignore
the attribute.)
[…] the user agent will accept a cookie with a
Domain attribute of "example.com" or of "foo.example.com" from
foo.example.com, but the user agent will not accept a cookie with a
Domain attribute of "bar.example.com" or of "baz.foo.example.com".
The 2 domains example.com and foo.example.com can only share cookies if the domain is explicitly named in the Set-Cookie header. Otherwise, the scope of the cookie is restricted to the request host.
For instance, if you sent the following header from foo.example.com:
Set-Cookie: name=value
Then the cookie won't be sent for requests to example.com. However if you use the following, it will be usable on both domains:
Set-Cookie: name=value; domain=example.com
In RFC 2109, a domain without a leading dot meant that it could not be used on subdomains, and only a leading dot (.example.com) would allow it to be used across subdomains.
However, modern browsers respect the newer specification RFC 6265, and will ignore any leading dot, meaning you can use the cookie on subdomains as well as the top-level domain.
In summary, if you set a cookie like the second example above from example.com, it would be accessible by foo.example.com, and vice versa.
For more details : https://stackoverflow.com/a/23086139/5466401
Actually, there is a simple and fully cross-browser support way for sharing cookies between original domain and subdomains but you should share it in setting time, for comfortable working with cookie stuffs in browser I'm using js-cookie and with the below setting cookie it could be shared between original domain and all of its subdomains:
Cookie.set('key', 'value', { domain: '.domain.com' })
// a . added before domain name
Hint: Adding this . will share cookie with all sub-subdomain.

Resources