I have a question related to Share cookie between subdomain and domain - what would happen if I set the domain while setting cookie as .com? Would the cookie be available to all .com websites?
Well-configured user-agents should reject such cookies, as explained in RFC 6265 section 5.3:
If the user agent is configured to reject "public suffixes" and the domain-attribute is a public suffix:
If the domain-attribute is identical to the canonicalized request-host:
Let the domain-attribute be the empty string.
Otherwise:
Ignore the cookie entirely and abort these steps.
NOTE: A "public suffix" is a domain that is controlled by a
public registry, such as "com", "co.uk", and "pvt.k12.wy.us".
This step is essential for preventing attacker.com from
disrupting the integrity of example.com by setting a cookie
with a Domain attribute of "com". Unfortunately, the set of
public suffixes (also known as "registry controlled domains")
changes over time. If feasible, user agents SHOULD use an
up-to-date public suffix list, such as the one maintained by
the Mozilla project at http://publicsuffix.org/.
Related
From both the documentation and this link, I already know that the fact is foo.example.com can set cookies for example.com by sending response with Domain = example.com in the Set-Cookie header. But why is this allowed?
For example, the fact is, a server (say, foo.example.com) cannot set cookies for its siblings (say, bar.example.com) or the domain names lower than it (also known as "its child", say, ide.foo.example.com), but it can set cookies for the domain names higher than it (also known as "its parents", in this case example.com.
Let me make the statement of the question even more clear by putting it into the real world. Just like apps on Google App Engine, foo.appspot.com obviously cannot set cookies for bar.appspot.com because they are two different apps, and they shouldn't affect each other's behavior. But why is it allowed for foo.appspot.com to set cookies for appspot.com by sending Domain = appspot.com in its response header? By doing this the foo.appspot.com app can actually affect other apps' behavior on Google App Engine, since the browser will send this cookie when visiting bar.appspot.com, the domain name of which is a child of appspot.com.
I learned all these things about cookies from the Web Development course on Udacity. But I'm really confused with this question. Can anybody help explain this? Thanks in advance. :-)
The link you provided is horribly outdated. Too bad people googling "cookie domain" will find it first.
I should write a better one; but for now, to quickly answer your question - it is about "public suffix" domain.
Can server "example.com" set a cookie for "com"? Nope, because "com" is a public suffix.
Can "foo.co.uk" set a cookie for "co.uk"? Nope, because "co.uk" is a public suffix.
It happens that "appspot.com" is also a public suffix; so "foo.appspot.com" cannot set a cookie with domain="appspot.com". (It can, but browsers will reject it)
Unfortunately, there's no algorithm to determine which is a public suffix. The list of all public suffix is maintained manually at https://publicsuffix.org/
I'm setting up basic authentication on a php site and found this page on the php manual showing the set up. What does "realm" mean here in the header?
header('WWW-Authenticate: Basic realm="My Realm"');
Is it the page page being requested?
From RFC 1945 (HTTP/1.0) and RFC 2617 (HTTP Authentication referenced by HTTP/1.1)
The realm attribute (case-insensitive) is required for all
authentication schemes which issue a challenge. The realm value
(case-sensitive), in combination with the canonical root URL of the
server being accessed, defines the protection space. These realms
allow the protected resources on a server to be partitioned into a set
of protection spaces, each with its own authentication scheme and/or
authorization database. The realm value is a string, generally
assigned by the origin server, which may have additional semantics
specific to the authentication scheme.
In short, pages in the same realm should share credentials. If your credentials work for a page with the realm "My Realm", it should be assumed that the same username and password combination should work for another page with the same realm.
A realm can be seen as an area (not a particular page, it could be a group of pages) for which the credentials are used; this is also the string that will be shown when the browser pops up the login window, e.g.
Please enter your username and password for <realm name>:
When the realm changes, the browser may show another popup window if it doesn't have credentials for that particular realm.
According to the RFC 7235, the realm parameter is reserved for defining protection spaces (set of pages or resources where credentials are required) and it's used by the authentication schemes to indicate a scope of protection.
For more details, see the quote below (the highlights are not present in the RFC):
2.2. Protection Space (Realm)
The "realm" authentication parameter is reserved for use by
authentication schemes that wish to indicate a scope of protection.
A protection space is defined by the canonical root URI (the scheme
and authority components of the effective request URI)
of the server being accessed, in combination with
the realm value if present. These realms allow the protected
resources on a server to be partitioned into a set of protection
spaces, each with its own authentication scheme and/or authorization
database. The realm value is a string, generally assigned by the
origin server, that can have additional semantics specific to the
authentication scheme. Note that a response can have multiple
challenges with the same auth-scheme but with different realms. [...]
Note 1: The framework for HTTP authentication is currently defined by the RFC 7235, which updates the RFC 2617 and makes the RFC 2616 obsolete.
Note 2: The realm parameter is no longer always required on challenges.
If evil.example.com sets a cookie with a domain attribute set to .example.com, a browser will include this cookie in requests to foo.example.com.
The Tangled Web notes that for foo.example.com such cookie is largely indistinguishable from cookies set by foo.example.com. But according to the RFC, the domain attribute of a cookie should be sent to the server, which would make it possible for foo.example.com to distinguish and reject a cookie that was set by evil.example.com.
What is the state of current browsers implementations? Is domain sent back with cookies?
RFC 2109 and RFC 2965 were historical attempts to standardise the handling of cookies. Unfortunately they bore no resemblance to what browsers actually do, and should be completely ignored.
Real-world behaviour was primarily defined by the original Netscape cookie_spec, but this was highly deficient as a specification, which has resulting in a range of browser differences, around -
what date formats are accepted;
how cookies with the same name are handled when more than one match;
how non-ASCII characters work (or don't work);
quoting/escapes;
how domain matching is done.
RFC 6265 is an attempt to clean up this mess and definitively codify what browsers should aim to do. It doesn't say browsers should send domain or path, because no browser in history has ever done that.
Because you can't detect that a cookie comes from a parent domain(*), you have to take care with your hostnames to avoid overlapping domains if you want to keep your cookies separate - in particular for IE, where even if you don't set domain, a cookie set on example.com will always inherit into foo.example.com.
So: don't use a 'no-www' hostname for your site if you think you might ever want a subdomain with separate cookies in the future (that shouldn't be able to read sensitive cookies from its parent); and if you really need a completely separate cookie context, to prevent evil.example.com injecting cookie values into other example.com sites, then you have no choice but to use completely separate domain names.
An alternative that might be effective against some attack models would be to sign every cookie value you produce, for example using an HMAC.
*: there is kind of a way. Try deleting the cookie with the same domain and path settings as the cookie you want. If the cookie disappears when you do so, then it must have had those domain and path settings, so the original cookie was OK. If there is still a cookie there, it comes from somewhere else and you can ignore it. This is inconvenient, impractical to do without JavaScript, and not watertight because in principle the attacker could be deleting their injected cookies at the same time.
The current standard for cookies is RFC 6265. This version has simplified the Cookie: header. The browser just sends cookie name=value pairs, not attributes like the domain. See section 4.2 of the RFC for the specification of this header. Also, see section 8.6, Weak Integrity, where it discusses the fact that foo.example.com can set a cookie for .example.com, and bar.example.com won't be able to tell that it's not a cookie it set itself.
I would believe Zalewski's book and his https://code.google.com/p/browsersec/wiki/Main over any RFCs. Browsers' implementations of a number of HTTP features are notoriously messy and non-standard.
I have a dev server in our office that is behind the firewall. The hostname is franklin. We name all our servers after scientists or inventors.
When I set an HTTP cookie:
Set-Cookie: user=kenny; expires=1245424860.11; Path=/; domain=franklin
The cookie doesn't set. I have tried the following with no luck.
.franklin
.franklin.local
franklin.local
.franklin.localdomain
franklin.localdomain
Do I have to set the hostname to something different or can I set this cookie through some magic I don't know already?
RFC 2109 says:
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 value for the Domain attribute contains no embedded dots or
does not start with a dot.
The value for the request-host does not domain-match the Domain
attribute.
And also:
Domain Defaults to the request-host.
If your host is franklin:
Cookies with domain=.franklin will be rejected, because it has no embedded dot.
Cookies with domain=.franklin.local will be rejected, because it does not match the actual host name of your server.
The solution is to rename your hostname to franklin.local or franklin.<tld> and set the domain attribute of the cookie accordingly (domain=.franklin.<tld>). Alternatively (as you found out), do not specify the domain, and let the user agent fallback to the request host.
Are you setting the cookie from the right domain? You should access the website over http://franklin/ otherwise it wouldn't work (see: same origin policy).
Due to weird domain/subdomain cookie issues that I'm getting, I'd like to know how browsers handle cookies. If they do it in different ways, it would also be nice to know the differences.
In other words - when a browser receives a cookie, that cookie MAY have a domain and a path attached to it. Or not, in which case the browser probably substitutes some defaults for them. Question 1: what are they?
Later, when the browser is about to make a request, it checks its cookies and filters out the ones it should send for that request. It does so by matching them against the requests path and domain. Question 2: what are the matching rules?
Added:
The reason I'm asking this is because I'm interested in some edge cases. Like:
Will a cookie for .example.com be available for www.example.com?
Will a cookie for .example.com be available for example.com?
Will a cookie for example.com be available for www.example.com?
Will a cookie for example.com be available for anotherexample.com?
Will www.example.com be able to set cookie for example.com?
Will www.example.com be able to set cookie for www2.example.com?
Will www.example.com be able to set cookie for .com?
Etc.
Added 2:
Also, could someone suggest how I should set a cookie so that:
It can be set by either www.example.com or example.com;
It is accessible by both www.example.com and example.com.
Although there is the RFC 2965 (Set-Cookie2, had already obsoleted RFC 2109) that should define the cookie nowadays, most browsers don’t fully support that but just comply to the original specification by Netscape.
There is a distinction between the Domain attribute value and the effective domain: the former is taken from the Set-Cookie header field and the latter is the interpretation of that attribute value. According to the RFC 2965, the following should apply:
If the Set-Cookie header field does not have a Domain attribute, the effective domain is the domain of the request.
If there is a Domain attribute present, its value will be used as effective domain (if the value does not start with a . it will be added by the client).
Having the effective domain it must also domain-match the current requested domain for being set; otherwise the cookie will be revised. The same rule applies for choosing the cookies to be sent in a request.
Mapping this knowledge onto your questions, the following should apply:
Cookie with Domain=.example.com will be available for www.example.com
Cookie with Domain=.example.com will be available for example.com
Cookie with Domain=example.com will be converted to .example.com and thus will also be available for www.example.com
Cookie with Domain=example.com will not be available for anotherexample.com
www.example.com will be able to set cookie for example.com
www.example.com will not be able to set cookie for www2.example.com
www.example.com will not be able to set cookie for .com
And to set and read a cookie for/by www.example.com and example.com, set it for .www.example.com and .example.com respectively. But the first (.www.example.com) will only be accessible for other domains below that domain (e.g. foo.www.example.com or bar.www.example.com) where .example.com can also be accessed by any other domain below example.com (e.g. foo.example.com or bar.example.com).
The previous answers are a little outdated.
RFC 6265 was published in 2011, based on the browser consensus at that time.
Since then, there has been some complication with public suffix domains. I've written an article explaining the current situation - http://bayou.io/draft/cookie.domain.html
To summarize, rules to follow regarding cookie domain:
The origin domain of a cookie is the domain of the originating request.
If the origin domain is an IP, the cookie's domain attribute must not be set.
If a cookie's domain attribute is not set, the cookie is only applicable to its origin domain.
If a cookie's domain attribute is set,
the cookie is applicable to that domain and all its subdomains;
the cookie's domain must be the same as, or a parent of, the origin domain
the cookie's domain must not be a TLD, a public suffix, or a parent of a public suffix.
It can be derived that a cookie is always applicable to its origin domain.
The cookie domain should not have a leading dot, as in .foo.com - simply use foo.com
As an example,
x.y.z.com can set a cookie domain to itself or parents - x.y.z.com, y.z.com, z.com. But not com, which is a public suffix.
a cookie with domain=y.z.com is applicable to y.z.com, x.y.z.com, a.x.y.z.com etc.
Examples of public suffixes - com, edu, uk, co.uk, blogspot.com, compute.amazonaws.com
I tested all the cases in the latest Chrome, Firefox, Safari in 2019.
Response to Added:
Will a cookie for .example.com be available for www.example.com? YES
Will a cookie for .example.com be available for example.com? YES
Will a cookie for example.com be available for www.example.com? NO, Domain without wildcard only matches itself.
Will a cookie for example.com be available for anotherexample.com? NO
Will www.example.com be able to set cookie for example.com? NO, it will be able to set cookie for '.example.com', but not 'example.com'.
Will www.example.com be able to set cookie for www2.example.com? NO. But it can set cookie for .example.com, which www2.example.com can access.
Will www.example.com be able to set cookie for .com? NO
For an extensive coverage review the contents of RFC2965. Of course that doesn't necessarily mean that all browsers behave exactly the same way.
However in general the rule for default Path if none specified in the cookie is the path in the URL from which the Set-Cookie header arrived. Similarly the default for the Domain is the full host name in the URL from which the Set-Cookie arrived.
Matching rules for the domain require the cookie Domain to match the host to which the request is being made. The cookie can specify a wider domain match by include *. in the domain attribute of Set-Cookie (this one area that browsers may vary). Matching the path (assuming the domain matches) is a simple matter that the requested path must be inside the path specified on the cookie. Typically session cookies are set with path=/ or path=/applicationName/ so the cookie is available to all requests into the application.
__Response to Added:__
Will a cookie for .example.com be available for www.example.com? Yes
Will a cookie for .example.com be available for example.com? Don't Know
Will a cookie for example.com be available for www.example.com? Shouldn't but... *
Will a cookie for example.com be available for anotherexample.com? No
Will www.example.com be able to set cookie for example.com? Yes
Will www.example.com be able to set cookie for www2.example.com? No (Except via .example.com)
Will www.example.com be able to set cookie for .com? No (Can't set a cookie this high up the namespace nor can you set one for something like .co.uk).
* I'm unable to test this right now but I have an inkling that at least IE7/6 would treat the path example.com as if it were .example.com.
The last (third to be exactly) RFC for this issue is RFC-6265 (Obsoletes RFC-2965 that in turn obsoletes RFC-2109).
According to it if the server omits the Domain attribute, the user agent will return the cookie only to the origin server (the server on which a given resource resides). But it's also warning that some existing user agents treat an absent Domain attribute as if the Domain attribute were present and contained the current host name (For example, if example.com returns a Set-Cookie header without a Domain attribute, these user agents will erroneously send the cookie to www.example.com as well).
When the Domain attribute have been specified, it will be treated as complete domain name (if there is the leading dot in attribute it will be ignored). Server should match the domain specified in attribute (have exactly the same domain name or to be a subdomain of it) to get this cookie. More accurately it specified here.
So, for example:
cookie attribute Domain=.example.com is equivalent to Domain=example.com
cookies with such Domain attributes will be available for example.com and www.example.com
cookies with such Domain attributes will be not available for another-example.com
specifying cookie attribute like Domain=www.example.com will close the way for www4.example.com
PS: trailing comma in Domain attribute will cause the user agent to ignore the attribute =(
The RFCs are known not to reflect reality.
Better check draft-ietf-httpstate-cookie, work in progress.
There are rules that determine whether a browser will accept the Set-header response header (server-side cookie writing), a slightly different rules/interpretations for cookie set using Javascript (I haven't tested VBScript).
Then there are rules that determine whether the browser will send a cookie along with the page request.
There are differences between the major browser engines how domain matches are handled, and how parameters in path values are interpreted. You can find some empirical evidence in the article How Different Browsers Handle Cookies Differently
Will www.example.com be able to set cookie for .com?
No, but example.com.fr may be able to set a cookie for example2.com.fr. Firefox protects against this by maintaining a list of TLDs: http://securitylabs.websense.com/content/Blogs/3108.aspx
Apparently Internet Explorer doesn't allow two-letter domains to set cookies, which I suppose explains why o2.ie simply redirects to o2online.ie. I'd often wondered that.
I was surprised to read section 3.3.2 about rejecting cookies:
https://www.rfc-editor.org/rfc/rfc2965
That says that a browser should reject a cookie from x.y.z.com with domain .z.com, because 'x.y' contains a dot. So, unless I am misinterpreting the RFC and/or the questions above, there could be questions added:
Will a cookie for .example.com be available for www.yyy.example.com? No.
Will a cookie set by origin server www.yyy.example.com, with domain .example.com, have it's value sent by the user agent to xxx.example.com? No.