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.
Related
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.
In the context of CORS, is it possible to coerce the browser to always send the Origin header with an FQDN? The target service should see Origin: http://website.intranet.example.com/page.html instead of Origin: http://website/page.html.
As the example implies this is an intranet environment and the goal is to filter request origins by subdomain to allow any page hosted on a domain machine (*.intranet.example.com) to make cross-origin requests to the service which is also hosted in the same domain. The problem (if you will) is that intranet sites are commonly addressed as http://website/ with the remainder implied by the connection-specific DNS suffix: intranet.example.com set via domain policy.
The only workaround I can think of is to require all the 'origin' pages to force canonical URLs (i.e. redirect //foo to //foo.intranet.example.com) with the least side effect of "ugly URLs".
In the CORS context, rather than trying to get Origin values the same for the short and the fully qualified domain name, you could just focus on whether the server should allow the request to proceed or not whether either Origin value is present:
Assuming that to allow the cross-origin request, the responding server only needs to respond with a suitable Access-Control-Allow-Origin response header, you could respond with the wildcard value to say any incoming Origin is ok:
Access-Control-Allow-Origin: *
If your client requires a specific domain instead of the wildcard, you could have the webserver just echo back the value of the incoming Origin header if you choose to allow the request to proceed, regardless of what the Origin value says it is.
e.g. in Apache, use the SetEnvIf and Header modules to write an environment variable containing the origin value if that value matches a specific regex, then if that variable exists write the Access-Control-Allow-Origin response header with the environment variable's value:
SetEnvIf Origin "(.+)" origin_header_value=$1
Header set Access-Control-Allow-Origin "%{origin_header_value}e" env=origin_header_value
If you need more fine grain control over whether the webserver includes the Access-Control-Allow-Origin header in this manner, you can just set a more restrictive regex in the SetEnvIf command instead of using .+.
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.
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.
is there any reason (safety?) why someone should rename the ASP.NET Session Cookie Name or is it just a senseless option of ASP.NET?
If you have several applications running under the same domain on the same server, you may well want to have seperate session cookie names for each one, so that they aren't sharing the same session state or worse still overwriting each other.
See also the notes for the Forms Auth cookie name:
Specifies the HTTP cookie to use for authentication. If multiple applications are running on a single server and each application requires a unique cookie, you must configure the cookie name in each Web.config file for each application.
1) It might (slightly) slow someone down who is (casually) looking for it.
2) You might want to hide the fact that you are running ASP.NET
Below link provides more information about why session cookies should be renamed.
https://www.owasp.org/index.php/Session_Management_Cheat_Sheet
"The name used by the session ID should not be extremely descriptive nor offer unnecessary details about the purpose and meaning of the ID.
The session ID names used by the most common web application development frameworks can be easily fingerprinted [0], such as PHPSESSID (PHP), JSESSIONID (J2EE), CFID & CFTOKEN (ColdFusion), ASP.NET_SessionId (ASP .NET), etc. Therefore, the session ID name can disclose the technologies and programming languages used by the web application.
It is recommended to change the default session ID name of the web development framework to a generic name, such as “id”."
With cookie prefixes, you can add a security attribute to your cookie by naming it a special way. So in that case renaming your ASP.NET session cookie does have an impact on security:
__Secure-… cookies can only be written from secure (HTTPS) sites.
__Host-… cookies can only be written from the same, secure domain. So not from subdomains or insecure (HTTP) sites.
According to the following specification, https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-cookie-prefixes-00, that modern browsers implement, the prefixes are used to make things more secure.
3.1. The "__Secure-" prefix
If a cookie's name begins with "__Secure-", the cookie MUST be:
Set with a "Secure" attribute
Set from a URI whose "scheme" is considered "secure" by the user
agent.
The following cookie would be rejected when set from any origin, as
the "Secure" flag is not set
Set-Cookie: __Secure-SID=12345; Domain=example.com
While the following would be accepted if set from a secure origin
(e.g. "https://example.com/"), and rejected otherwise:
Set-Cookie: __Secure-SID=12345; Secure; Domain=example.com
3.2. The "__Host-" prefix
If a cookie's name begins with "__Host-", the cookie MUST be:
Set with a "Secure" attribute
Set from a URI whose "scheme" is considered "secure" by the user
agent.
Sent only to the host which set the cookie. That is, a cookie
named "__Host-cookie1" set from "https://example.com" MUST NOT
contain a "Domain" attribute (and will therefore be sent only to
"example.com", and not to "subdomain.example.com").
Sent to every request for a host. That is, a cookie named
"__Host-cookie1" MUST contain a "Path" attribute with a value of
"/".
The following cookies would always be rejected:
Set-Cookie: __Host-SID=12345 Set-Cookie: __Host-SID=12345;
Secure Set-Cookie: __Host-SID=12345; Domain=example.com
Set-Cookie: __Host-SID=12345; Domain=example.com; Path=/
Set-Cookie: __Host-SID=12345; Secure; Domain=example.com; Path=/
I think its mainly a matter of taste. Some people/companies want control every aspect of their web apps and might just use another name for consistency with other cookie names. For example, if you use very short one-character parameter names throughout your app you might not like session cookie names like ASPSESSID.
Security reasons might apply but security through obscurity is rather weak in my opinion.