How Different Browsers Handle Cookies Differently

24-JUL-2011, last update 18-AUG-2013
A cookie is a piece of data that a website can store in user's browser. You can find a lot of good information about these HTTP Cookies on Wikipedia.

This article describes how they are implemented in the different brands of web browsers, and focuses on the differences. Some differences are quite shocking! The article might explain some odd behavior you have seen from time to time, or explain incident reports from your users.

Table of Contents

Introduction - The Basics

A web site can write a cookie using a Set-Cookie response header. In its simplest form, it will only contain a name-value pair, for example:

  Set-Cookie: test=helloworld;

There are many attributes that can be used on a cookie response header, such as adding a domain, path and expires information. Here is an example with many of such attributes:
  Set-Cookie: test=helloworld; expires=Thu, 01-Jan-1970 00:00:10 GMT; domain=.mydomain.com; path=/; HttpOnly; Secure

The web browser will or will not accept the cookie that the web server tries to set. It will not tell the user, although the browser might ask the user whether or not to accept the cookie.

Whenever a page is requested from the web server, the browser will check whether it needs to send a cookie (or multiple cookies). If it does, it will send a request header like this:

  Cookie: test=helloworld;

The browser will not send any of the other information it might have received, such as when the cookie expires, the path or whether it is a secure cookie.

It is not only the server that can set cookies. In most situations, it is also possible to set cookies using client-side Javascript.

This article describes the effect of the different properties and situations regarding cookies.

Effects of PATH

The web server can use the path attribute to specify what URL paths qualify for the cookie. for example:

  Set-Cookie: test=helloworld; path=/products;

The path in the example indicates that only URLs that start with "/products" should use the cookie. So a URL like http://www.mydomain.com/products/ball.html should use it, and a URL like http://www.mydomain.com/introduction.html should not.

It also means that in this example, on page http://www.mydomain.com/products/ball.html the DOM would expose the "test=helloworld" information in the document.cookie object, accessible with Javascript, but document.cookie would be empty for Javascript that is executed in the context of http://www.mydomain.com/introduction.html

Set-cookie - Path

It is perfectly valid for page like http://mydomain.com/goodbye/world.htm to write a cookie with the path /hello. When setting cookies, the path does not have to match.

Cookie matching - Path

There are URLs in different shapes and forms. Here are a few examples:

The table below shows for each brand of web browser whether it considers the URL to match the path.
The browser will only send it to the server if it matches.

Cookie pathWhen requesting URLSafari 5,
Chrome 12,
Opera 10,
Netscape 4
FireFox 3,
FireFox 5,
FireFox 23
Internet Explorer 6,
Internet Explorer 7,
Internet Explorer 8,
Internet Explorer 9,
Internet Explorer 10
path=/hellohttp://mydomain.com/goodbye/world.htmno matchno matchno match
path=/hellohttp://mydomain.com/hello/world.htmmatchmatchmatch
path=/hello/world.htmhttp://mydomain.com/hello/world.htmmatchmatchmatch
path=/hello/world.htmhttp://mydomain.com/hello/world.htm?id=5matchmatchmatch
path=/hello/world.htm?id=5http://mydomain.com/hello/world.htmno matchno matchMATCH!
path=/hello/world.htm?id=5http://mydomain.com/hello/world.htm?id=5NO MATCH!matchmatch

As you can see in the table, different browser behave differently when query string parameters are used in the cookie path. Therefore, I recommend against using parameters in the cookie path.

The table below shows for each brand of web browser if the cookie is exposed to Javascript based on the path matching.

Cookie pathJavascript on page at URLSafari 4,
Safari 5,
Chrome 28
FireFox 14,
FireFox 22
Internet Explorer 7,
Internet Explorer 9,
Internet Explorer 10
path=/hellohttp://mydomain.com/goodbye/world.htmnot exposednot exposednot exposed
path=/hellohttp://mydomain.com/hello/world.htmexposedexposedexposed
path=/hello/world.htmhttp://mydomain.com/hello/world.htmexposedexposedNOT EXPOSED!
path=/hello/world.htmhttp://mydomain.com/hello/world.htm?id=5exposedexposedNOT EXPOSED!
path=/hello/world.htm?id=5http://mydomain.com/hello/world.htmnot exposednot exposednot exposed
path=/hello/world.htm?id=5http://mydomain.com/hello/world.htm?id=5NOT EXPOSED!exposedNOT EXPOSED!

In addition to the earlier recommendation never to use query string parameters in the cookie's path, this table shows that is it best not to use the actual page name in the path either. As the name suggests, it is best to use the cookie path only for the path of a web page.

Effects of DOMAIN

The web server can use the domain attribute to specify what URL domain names qualify for the cookie. for example:

  Set-Cookie: test=helloworld; domain=.mydomain.com;

The domain in the example indicates that only URLs that are "mydomain.com", or are subdomains of it should use the cookie. So a URL like http://www.mydomain.com/products/ball.html should use it, and a URL like http://cnn.com/ should not.

Set-cookie - Domain

The table below shows how web browsers react if no domain is present in the Set-Cookie header.

Requested URLdomain omitted
in the
Set-Cookie header
Safari 5,
Chrome 12,
Opera 11,
FireFox 3,
FireFox 5,
FireFox 23,
Internet Explorer 6,
Internet Explorer 7,
Internet Explorer 8,
Internet Explorer 9,
Internet Explorer 10
Netscape 4
http://go/ acceptednot accepted
http://go.go/ acceptednot accepted
http://good.go/ acceptedaccepted
http://www.good.go/ acceptedaccepted

Because of security reasons, a page is not allowed to set cookies for another domain. It is only allowed to specify the current domain or higher levels of that domain, up to and including the second level domain.

For example a page at http://this.is.an.example.com/ is allowed to specify the domains this.is.an.example.com, is.an.example.com, an.example.com and example.com.

The table below shows for each brand of web browser whether it will accept the returned cookie with a specified domain for the requested URL.

Requested URLdomain
in the
Set-Cookie header
FireFox 3,
FireFox 5,
Opera 11
Internet Explorer 6,
Internet Explorer 7,
Internet Explorer 8,
Internet Explorer 9,
Internet Explorer 10
Safari 5Chrome 12Netscape 4
http://go/domain=goacceptednot acceptedacceptednot acceptednot accepted
http://go/domain=.goacceptednot acceptedacceptednot acceptednot accepted
http://go.go/domain=gonot acceptednot acceptedACCEPTED!not acceptednot accepted
http://go.go/domain=.gonot acceptednot acceptedACCEPTED!not acceptednot accepted
http://go.go/domain=go.goacceptedNOT ACCEPTED!acceptedacceptedNOT ACCEPTED!
http://go.go/domain=.go.goacceptedNOT ACCEPTED!acceptedacceptedNOT ACCEPTED!
http://good.go/domain=good.goacceptedacceptedacceptedacceptedNOT ACCEPTED!
http://good.go/domain=.good.goacceptedacceptedacceptedacceptedNOT ACCEPTED!
http://www.good.go/domain=good.goacceptedacceptedacceptedacceptedNOT ACCEPTED!
http://www.good.go/domain=.good.goacceptedacceptedacceptedacceptedaccepted
http://www.good.go/domain=www.good.goacceptedacceptedacceptedacceptedaccepted

As you can see, there are a few remarkable things in this table:
I therefore recommend that you run your website on a second level domain where your second level consists of at least 3 characters (for example cnn.com), or use a third level domain (for example www.hi.nl).

Cookie matching - Domain

Once the browser has accepted a cookie domain, it will use that information to determine whether the cookie should be used when requesting a URL.

The table below shows for each brand of web browser whether it considers the URL to match the domain of the available cookie.

Cookie domainWhen requesting URLFireFox 3,
FireFox 5
Internet Explorer 6,
Internet Explorer 7,
Internet Explorer 8,
Internet Explorer 9
Safari 5Chrome 12Opera 11Netscape 4
domain=gohttp://go/matchno matchmatchno matchmatchno match
domain=.gohttp://go/matchno matchmatchno matchmatchno match
domain=gohttp://good.go/no matchno matchmatchno matchno matchno match
domain=.gohttp://good.go/no matchno matchmatchno matchno matchno match
domain=good.gohttp://good.go/matchmatchmatchmatchmatchNO MATCH!
domain=good.gohttp://www.good.go/matchmatchmatchmatchmatchNO MATCH!
domain=.good.gohttp://www.good.go/matchmatchmatchmatchmatchmatch
domain=www.good.gohttp://good.go/no matchno matchno matchno matchno matchno match
domain=www.good.gohttp://www.good.go/matchmatchmatchmatchmatchmatch

If you disregard the old Netscape 4 web browser, there are no surprises in this table.

Effects of HTTPONLY

The web server can use the HttpOnly attribute to specify that the cookie use should be restricted to the HTTP(S) connection. In other words, it will not be exposed in the DOM, it will not be available in Javascript.

  Set-Cookie: test=helloworld; HttpOnly;

In the example, the cookie test would not be available in any client-side Javascript code.

The table shows for each brand of web browser if it exposes the cookie to Javascript when the HttpOnly attribute was used when the cookie was set.

Cookie HttpOnlyJavascript on page at URLSafari 4,
Safari 5,
Safari 6,
Opera 12,
Chrome 28,
Internet Explorer 7,
Internet Explorer 9,
Internet Explorer 10,
FireFox 22
HttpOnlyhttp://mydomain.com/hello/world.htmnot exposed,
DOM cookie cleared

The next table shows what happens if Javascript attempts to write a cookie that is already available as HttpOnly cookie.

Cookie HttpOnlyJavascript writes the same cookieSarari 4,
Safari 5,
Safari 6,
Opera 12
Chrome 28,
Internet Explorer 7,
Internet Explorer 9,
Internet Explorer 10,
FireFox 22
test=helloworld; HttpOnly;document.cookie='test=bye';COOKIE IS OVERRIDDEN!
HttpOnly status is lost
Javascript is ignored

What this table shows, is that Safari and Opera provide only half the protection that might be expected from the HttpOnly attribute. Although they do prevent exposure to any Javascript, they don't prevent cookie poisoning, which increases the security risks if there's ever a cross site scripting problem (or cross site scripting bug).

Effects of SECURE

The web server can use the Secure attribute to specify that the cookie should only be sent over an HTTPS connection, and only be accessible on a page served over HTTPS.

  Set-Cookie: test=helloworld; Secure;

In the example, the cookie test will not be sent to the server if an HTTP page is requested, nor will it be available in any client-side Javascript code on a page that is requested over HTTP.

The table shows for each brand of web browser if the cookie is used over HTTP when the Secure attribute was used when the cookie was set.

Cookie SecureWhen requesting URLSafari 4,
Safari 5,
Netscape 4,
Opera 12,
Chrome 28,
Internet Explorer 6,
Internet Explorer 7,
Internet Explorer 9,
Internet Explorer 10,
FireFox 12,
FireFox 23
Securehttp://mydomain.com/hello/world.htmnot sent
no DOM cookie
Securehttps://mydomain.com/hello/world.htmsent,
DOM cookie available

The next table shows what happens if the relevant cookie already exists and the server writes it again with the Secure attribute.

Cookie presentRequested pageSet-Cookie headerSafari 4,
Safari 5,
Netscape 4,
Opera 12,
Chrome 28,
Internet Explorer 6,
Internet Explorer 7,
Internet Explorer 9,
Internet Explorer 10,
FireFox 12,
FireFox 23
test=helloworld; https://mydomain.com/hello/world.htmtest=bye; Secure;Cookie is overridden
Cookie only used on HTTPS
test=helloworld; Secure;https://mydomain.com/hello/world.htmtest=bye;Cookie is overridden
Cookie on any protocol
test=helloworld; Secure;http://mydomain.com/hello/world.htmtest=bye;Cookie is overridden
Cookie on any protocol
test=helloworld; http://mydomain.com/hello/world.htmtest=bye; Secure;COOKIE IS OVERRIDDEN!
Cookie only used on HTTPS
test=helloworld; Secure;http://mydomain.com/hello/world.htmtest=bye; SecureCOOKIE IS OVERRIDDEN!
Cookie only used on HTTPS

Now you'd think that the browser wouldn't accept any cookies marked as Secure over an insecure connection, but as you can see, you'd be wrong. Every browser accepts secure cookies from an HTTP response.

In defense of the browser vendors: an HTTPS connection does not guarantee encryption, and if encryption is used, it doesn't guarantee encryption quality. So although it is certain that the data will be unencrypted over HTTP, there is no guarantee of any industry strength encrypting on HTTPS connections.

Please note that when a cookie is sent to the server, there is no indication of Secure (or HttpOnly) in the request, so the server will never know with what settings the cookie came about.

To be continued, with topics like how 3rd party cookies are handled and the rules of cookie precedence...

Mail your comments to gertjans@xs4all.nl.