Why can foo.example.com set cookies for example.com? - http

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/

Related

Can cookie be set against top level domain like .com

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/.

Is domain attribute of a cookie sent back to a server?

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.

How to respect "Serve static content from a cookieless domain" page speed rule in IIS6?

How to respect "Serve static content from a cookieless domain" page speed rule in IIS6?
To create a cookieless site (or subdomain, which is a very common best-practice) in IIS6/IIS7/IIS7.5 is simple : you need to tell the website that you are not to use cookies :) Which means in IIS terms, not to use a session.
This can be achieved in IIS6/IIS7 via two ways.
Modifying the Web.config file (my personal recommendation)
Using the IIS Manager GUI to find the setting and changing it.
IMPORTANT
Before you do any testing, you must must must clear all cookies (or all cookies for the domain u are testing) otherwise, they will get passed along even if u have done all the steps.
1. Via Config File
You need to define the session state to off.
<system.web>
<sessionState cookieName="What_ever" mode="Off" />
</system.web>
NOTE: Please note that the attribute cookieless (true|false) does NOT mean 'send cookies/do not sent cookies). That's for using sessions with/without cookies ... and passes some cookie guid into the url instead (if set to true).
2. Via Gui
Hope this Helps (i assume u know how to test that no cookies are working/not working...)
What this means is that your content needs to come from a domain that has no cookies attached to it. StackOverflow.com is an example of a site that does this. You will notice that all SO's static content comes from a domain called sstatic.net.
http://sstatic.net/stackoverflow/all.css
http://sstatic.net/js/master.js
This is so that the client and the server don't have to waste resources on actually parsing and handling cookie data. The good news is, you can use a sub-domain, assuming that you set your cookie path correctly.
Yahoo Best Practices for Speeding Up
Your Web Site
Use Cookie-free Domains for Components
When the browser makes a request for a
static image and sends cookies
together with the request, the server
doesn't have any use for those
cookies. So they only create network
traffic for no good reason. You should
make sure static components are
requested with cookie-free requests.
Create a subdomain and host all your
static components there. If your
domain is www.example.org, you can
host your static components on
static.example.org. However, if you've
already set cookies on the top-level
domain example.org as opposed to
www.example.org, then all the requests
to static.example.org will include
those cookies. In this case, you can
buy a whole new domain, host your
static components there, and keep this
domain cookie-free. Yahoo! uses
yimg.com, YouTube uses ytimg.com,
Amazon uses images-amazon.com and so
on.
Another benefit of hosting static
components on a cookie-free domain is
that some proxies might refuse to
cache the components that are
requested with cookies. On a related
note, if you wonder if you should use
example.org or www.example.org for
your home page, consider the cookie
impact. Omitting www leaves you no
choice but to write cookies to
*.example.org, so for performance reasons it's best to use the www
subdomain and write the cookies to
that subdomain.
create subdomain ( for example static.example.com ) and store all static content(images, css, js) here

Can subdomain.example.com set a cookie that can be read by example.com?

I simply cannot believe this is quite so hard to determine.
Even having read the RFCs, it's not clear to me if a server at subdomain.example.com can set a cookie that can be read by example.com.
subdomain.example.com can set a cookie whose Domain attribute is .example.com. RFC 2965 seems to explicitly state that such a cookie will not be sent to example.com, but then equally says that if you set Domain=example.com, a dot is prepended, as if you said .example.com. Taken together, this seems to say that if example.com returns sets a cookie with Domain=example.com, it doesn't get that cookie back! That can't be right.
Can anyone clarify what the rules really are?
Yes.
If you make sure to specify that the domain is .example.com, then *.example.com and example.com can access it.
It's that principle that allows websites that issue cookies when somebody goes to www.website.com to access cookies when someone leaves off the www, going to website.com.
EDIT: From the PHP documentation about cookies:
domain The domain that the cookie is
available. To make the cookie
available on all subdomains of
example.com then you'd set it to
'.example.com'. The . is not required
but makes it compatible with more
browsers. Setting it to
www.example.com will make the cookie
only available in the www subdomain.
Refer to tail matching in the » spec
for details.
http://php.net/manual/en/function.setcookie.php
And it's not unique to PHP.

Cookie Domain Precedence?

I have a few sites. Each site is a localized version serving up content specific to the a given set of locales. There is also a World Wide or "Global" site. I have them setup as follows:
http://mydomain.com
http://us.mydomain.com
http://uk.mydomain.com
etc...
I am trying to track activity on each application using a cookie. The cookie name for each site is the same, and using the default settings for domain (i.e. in .net I am not specifying a value for httpCookie.Domain - I am leaving it default).
Everything works fine when I am visiting my "locale specific" sites, but once I visit the "global" site, it seems that the cookie from this site is used when I go back to visit my "locale specific" sites, rather than the cookie issued for the "locale specific" site.
Any ideas on how to get my "global" cookie from taking precedence over my "local specific" cookie on the "locale specific" sites?
In most browsers, setting a cookie without a ‘domain’ makes it only valid on the current hostname. This can't otherwise be achieved by setting any value on ‘domain’; if this behaviour is what you want you must omit the ‘domain’ parameter.
However in IE, any cookie you set without a ‘domain’ will get an implicit ‘domain’ of the current hostname. This means if you set a cookie on ‘example.com’ you can't stop it being sent to ‘sub.example.com’.
Therefore you can't have subdomains that don't share part of the security context of the parent domain. If you want to keep a subdomain apart from its parent you must (as JustLoren suggested) make the main site www.example.com and not just example.com.
When two cookies with different domains are valid, browsers will typically send them both, so you can expect a document.cookie like 'a=b; a=c'. If your cookie-reading layer doesn't expect multiple cookies with the same name, one of those will disappear (you don't get any control over which).
The other approach, if you don't care about putting boundaries between the other sites and the main one, would be just to use different cookie names on the different subsites.
bobince is right about the unusual behavior of Internet Explorer. Note that Edge works differently, more like FireFox (for this aspect).
If you don't set any cookie properties, then you will probably run into problems with the path. In your case the property path=/ would be a good choice.
Note that there are many differences between browsers in the way they handle cookies. If you are interested, you can read How Different Browsers Handle Cookies Differently

Resources