How Different Browsers Handle Cookies Differently

24-JUL-2011, last update 21-FEB-2018
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. The specification can be found in RFC 6265.

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,
Safari 11,
Chrome 12,
Chrome 63,
Opera 10,
Netscape 4
FireFox 3,
FireFox 23,
FireFox 57
Internet Explorer 6,
Internet Explorer 7,
Internet Explorer 8,
Internet Explorer 9,
Internet Explorer 10,
Internet Explorer 11,
Edge 40
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,
Safari 11,
Chrome 28,
Chrome 63
FireFox 14,
FireFox 22,
FireFox 57
Internet Explorer 7,
Internet Explorer 9,
Internet Explorer 10,
Internet Explorer 11,
Edge 40
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.

Test case 1 - path

http://v8.prnx.net/goodbye/set-path1.asp
http://v8.prnx.net/goodbye/world.asp
http://v8.prnx.net/hello/world.asp

Test case 2 - path + name

http://v8.prnx.net/hello/set-path2.asp
http://v8.prnx.net/hello/world2.asp
http://v8.prnx.net/hello/world2.asp?id=5

Test case 3 - path + name + parameter

http://v8.prnx.net/hello/set-path3.asp
http://v8.prnx.net/hello/world3.asp
http://v8.prnx.net/hello/world3.asp?id=5

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 - No Domain

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

If the cookie is accepted, it is only used for the exact domain of the requested URL.

Requested URL domain omitted
in the
Set-Cookie header
Safari 5,
Chrome 12,
Opera 11,
FireFox 3,
FireFox 58,
Internet Explorer 6,
Internet Explorer 11,
Edge 40
Netscape 4 Internal
representation
of domain
http://go/ acceptednot acceptedgo
http://go.go/ acceptednot acceptedgo.go
http://good.go/ acceptedacceptedgood.go
http://www.good.go/ acceptedacceptedwww.good.go

Cookie matching - No Domain

Once the browser has accepted a cookie for a domain or domain hierarchy, it will use that information to determine whether the cookie should be sent 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.

Note that domains without a leading dot can only result from a Set Cookie operation that did not specify a domain.

Internal
representation
of domain
When requesting URLFireFox 3,
FireFox 12,
Edge 40
Internet Explorer 6,
Internet Explorer 11
Safari 5 Chrome 12,
Chrome 36
Opera 11 Netscape 4
domain=gohttp://go/matchmatchmatchno matchmatchno match
domain=gohttp://good.go/no matchMATCHmatchno matchno matchno match
domain=good.gohttp://good.go/matchmatchmatchmatchmatch?
domain=good.gohttp://www.good.go/no matchMATCHno matchno match?NO MATCH!
domain=www.good.gohttp://good.go/no matchno matchno matchno matchno matchno match
domain=www.good.gohttp://www.good.go/matchmatchmatchmatchmatchmatch

The big surpise in this table, is that Internet Explorer will use cookies for subdomains. This is a security vulnerability.

Test case 4 - no domain

-- Requires DNS configuration for go and go.go to refer to the IP address of prnx.net
http://go/goodbye/set-path1.asp
http://go/hello/world.asp
http://go.go/hello/world.asp
http://go.go/goodbye/set-path1.asp
http://go.go/hello/world.asp
http://prnx.net/goodbye/set-path1.asp
http://prnx.net/hello/world.asp
http://v8.prnx.net/hello/world.asp
http://v8.prnx.net/goodbye/set-path1.asp
http://v8.prnx.net/hello/world.asp

Set-cookie - Domain

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.

If the cookie is accepted, it is used for the specified domain and all its subdomains. Typically, this behavior is expressed with a "wildcard" dot prefixed to the domain in the internal representation.

Requested URL domain
in the
Set-Cookie header
FireFox 3,
FireFox 5, FireFox 33
Internet Explorer 6 - 11 Safari 5 Chrome 12,
Edge 40
Netscape 4 Opera 11 Internal
representation
of domain
http://go/domain=goacceptednot acceptedacceptednot acceptednot acceptedaccepted.go
http://go.go/domain=gonot acceptednot acceptedACCEPTED!not acceptednot acceptednot accepted.go
http://go/domain=.goacceptednot acceptedacceptednot acceptednot acceptedaccepted.go
http://go.go/domain=.gonot acceptednot acceptedACCEPTED!not acceptednot acceptednot accepted.go
http://go.go/domain=go.goacceptedNOT ACCEPTED!acceptedacceptedNOT ACCEPTED!accepted.go.go
http://go.go/domain=.go.goacceptedNOT ACCEPTED!acceptedacceptedNOT ACCEPTED!accepted.go.go
http://good.go/domain=good.goacceptedacceptedacceptedacceptedNOT ACCEPTED!accepted.good.go
http://www.good.go/domain=good.goacceptedacceptedacceptedacceptedNOT ACCEPTED!accepted.good.go
http://good.go/domain=.good.goacceptedacceptedacceptedacceptedNOT ACCEPTED!accepted.good.go
http://www.good.go/domain=.good.goacceptedacceptedacceptedacceptedacceptedaccepted.good.go
http://www.good.go/domain=www.good.goacceptedacceptedacceptedacceptedacceptedaccepted.www.good.go
http://good.go/domain=www.good.gonot acceptednot acceptednot acceptednot acceptednot accepted?.www.good.go
http://also.good.go/domain=www.good.gonot acceptednot acceptednot acceptednot acceptednot accepted?.www.good.go

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 for a domain or domain hierarchy, it will use that information to determine whether the cookie should be sent 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.

Note that domains without a leading dot can only result from a Set Cookie operation that did not specify a domain. The leading dot in the Cookie domain is a wildcard to indicate a domain hierarchy.

Internal
representation
of domain
When requesting URLFireFox 3,
FireFox 5,
FireFox 12
Internet Explorer 6,
Internet Explorer 11,
Edge 40
Safari 5 Chrome 12,
Chrome 36
Opera 11 Netscape 4
domain=.gohttp://go/matchno matchmatchno matchmatchno match
domain=.gohttp://good.go/no matchno matchmatchno matchno matchno match
domain=.good.gohttp://www.good.go/matchmatchmatchmatchmatchmatch

Test case 5 - tld

http://go.go/hello/set-domain1.asp
http://go.go/hello/domain1.asp
http://go/hello/domain1.asp
http://go/hello/set-domain1.asp
http://go/hello/domain1.asp

Test case 6 - wildcard + tld

http://go.go/hello/set-domain2.asp
http://go.go/hello/domain2.asp
http://go/hello/domain2.asp
http://go/hello/set-domain2.asp
http://go/hello/domain2.asp

Test case 7 - 2-letter sld

http://go.go/hello/set-domain3.asp
http://go.go/hello/domain3.asp

Test case 8 - wildcard + 2-letter sld

http://go.go/hello/set-domain4.asp
http://go.go/hello/domain4.asp

Test case 9 - sld

http://v8.prnx.net/hello/set-domain5.asp
http://v8.prnx.net/hello/domain5.asp
http://prnx.net/hello/domain5.asp
http://prnx.net/hello/set-domain5.asp
http://prnx.net/hello/domain5.asp

Test case 10 - wildcard + sld

http://v8.prnx.net/hello/set-domain6.asp
http://v8.prnx.net/hello/domain6.asp
http://prnx.net/hello/domain6.asp
http://prnx.net/hello/set-domain6.asp
http://prnx.net/hello/domain6.asp

Test case 11 - third ld

http://prnx.net/hello/set-domain7.asp
http://prnx.net/hello/domain7.asp
http://v8.prnx.net/hello/domain7.asp
http://x8.prnx.net/hello/domain7.asp
http://x8.prnx.net/hello/set-domain7.asp
http://x8.prnx.net/hello/domain7.asp
http://v8.prnx.net/hello/domain7.asp
http://v8.prnx.net/hello/set-domain7.asp
http://v8.prnx.net/hello/domain7.asp

Cookie matching - Multiple domain matches

If you request a URL, cookies from multiple domains might apply. For example, when requesting http://this.is.an.example.com/ there may be cookies for the exact domain this.is.an.example.com and for the wildcard domains .this.is.an.example.com, .is.an.example.com, .an.example.com and .example.com.

When multiple cookies apply, the browser may choose to send one, some or all of them as part of the Cookie request header. For example, the browser might send the following header.
  Cookie: test=one; test=two

Typically, when the application on the server inspects the cookie ("test" in the example), the first value is returned ("one" in the example).

The table below shows for each brand of web browser in which order multiple cookies are reproduced.

Requested
domain
at T=0
Set-Cookie header
at T=0
Requested
domain
at T=1
Set-Cookie header
at T=1
Requested
domain
at T=2
Set-Cookie header
at T=2
Requested
domain
after that
FireFox 56,
FireFox 58,
Chrome 64
Internet Explorer 10,
Internet Explorer 11,
Edge 40
Safari 5,
Safari 6
good.goSet-Cookie: x=2; domain=good.gowww.good.goSet-Cookie: x=0 www.good.goCOOKIE: X=2; X=0 COOKIE: X=2; X=0 Cookie: x=0; x=2
good.goSet-Cookie: x=2; domain=good.go www.good.goSet-Cookie: x=0, y=0 good.goSet-Cookie: y=2, domain=good.go www.good.goCOOKIE: X=2; y=0; x=0; y=2 COOKIE: X=2; Y=2; y=0; x=0 Cookie: x=0; y=0; y=2; x=2
www.good.goSet-Cookie: x=0good.goSet-Cookie: x=2; domain=good.go www.good.goCookie: x=0; x=2 Cookie: x=0; x=2 Cookie: x=0; x=2
good.goSet-Cookie: x=2; domain=good.gowww.good.goSet-Cookie: x=3; domain=www.good.go www.good.goCOOKIE: X=2; X=3 COOKIE: X=2; X=3 Cookie: x=3; x=2
www.good.goSet-Cookie: x=3; domain=www.good.gogood.goSet-Cookie: x=2; domain=good.go www.good.goCookie: x=3; x=2 Cookie: x=3; x=2 Cookie: x=3; x=2

As you can see, FireFox and Chrome list the cookies in order of creation instead of order of precedence.
Internet Explorer lists the cookies based on the first created cookie.
Since the context (the internal representation of the domain) is not sent in the Cookie header - and therefore cannot be established by the server - it is the browser's responsibility to send the cookie with the most selective domain first, the way Safari does it.

Test case 12 - upper + no domain

-- Restart browser or clear cookies before this test
http://prnx.net/hello/set-domain8a.asp
http://v8.prnx.net/hello/set-domain8b.asp
http://v8.prnx.net/hello/domain8.asp
http://prnx.net/hello/set-domain9a.asp
http://v8.prnx.net/hello/domain9.asp

Test case 13 - no domain + upper

-- Restart browser or clear cookies before this test
http://v8.prnx.net/hello/set-domain10a.asp
http://prnx.net/hello/set-domain10b.asp
http://v8.prnx.net/hello/domain10.asp

Test case 14 - upper domain + domain

-- Restart browser or clear cookies before this test
http://prnx.net/hello/set-domain11a.asp
http://v8.prnx.net/hello/set-domain11b.asp
http://v8.prnx.net/hello/domain11.asp

Test case 15 - upper domain + domain

-- Restart browser or clear cookies before this test
http://v8.prnx.net/hello/set-domain12a.asp
http://prnx.net/hello/set-domain12b.asp
http://v8.prnx.net/hello/domain12.asp

Effects of SAMESITE

The web server can use the SameSite attribute to specify that the cookie use should be restricted to callers from the same domain. The main purpose for this attribute is to prevent Cross Site Request Forgery (CSRF). If the browser decides that the context does not conform to the policy, then follow-up calls to the domain do not include the cookies with the SameSite property. For detailed information you can look at the standards proposal.

  Set-Cookie: test=someID; SameSite=Strict; domain=.mydomain.com; path=/;

In the example, the client would not send this cookie if the call is made from website that is no subdomain of mydomain.com.

The table shows for each brand of web browser if it conforms to the SameSite policy of the cookie.

Set-Cookie header at T=0 From webpage at URL Action at T=1 Safari 5, Safari 10,
FireFox 56,
FireFox 58,
Internet Explorer 11,
Edge 40
Chrome 56,
Chrome on Android
Set-Cookie: x=1; domain=good.go; SameSite=Stricthttp://other.go/iframe src="//good.go/"COOKIE SENT!not sent
Set-Cookie: x=1; domain=good.go; SameSite=Laxhttp://other.go/iframe src="//good.go/"COOKIE SENT!not sent
Set-Cookie: x=1; domain=good.go; SameSite=Stricthttp://other.go/POST action="//good.go/"COOKIE SENT!not sent
Set-Cookie: x=1; domain=good.go; SameSite=Laxhttp://other.go/POST action="//good.go/"COOKIE SENT!not sent
Set-Cookie: x=1; domain=good.go; SameSite=Stricthttp://other.go/A href="//good.go/"COOKIE SENT!not sent
Set-Cookie: x=1; domain=good.go; SameSite=Laxhttp://other.go/A href="//good.go/"cookie sentcookie sent

What this table shows, is that this (proposed) standard lacks supports from most major browsers; it would not be smart to use this standard as the only line of defense against CSRF.

Test case 16

http://v8.prnx.net/hello/set-samesite.asp
http://v8.prnx.net/hello/set-samesite2.asp
http://gertjans.home.xs4all.nl/javascript/get-samesite.html

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 6,
Opera 12,
Chrome 28,
Internet Explorer 7,
Internet Explorer 11,
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 11,
Edge 40,
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 is a security vulnerability.

Test case 17

http://v8.prnx.net/hello/set-httponly.asp
http://v8.prnx.net/hello/httponly.asp
http://v8.prnx.net/hello/set-httponly2.asp
http://v8.prnx.net/hello/httponly.asp
http://v8.prnx.net/hello/set-httponly.asp
http://v8.prnx.net/hello/httponly.asp

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 present Requested page Set-Cookie header Safari 4,
Safari 10,
Netscape 4,
Opera 12,
Chrome 28,
Internet Explorer 6,
Internet Explorer 11,
Edge 40,
FireFox 12,
FireFox 23
FireFox 56,
FireFox 58,
Chrome 64
test=helloworld; Secure;https://mydomain.com/hello/world.htmtest=bye;Cookie is overridden
Cookie on any protocol
Cookie is overridden
Cookie on any protocol
test=helloworld; Secure;http://mydomain.com/hello/world.htmtest=bye;Cookie is overridden
Cookie on any protocol
Cookie is retained
test=helloworld; https://mydomain.com/hello/world.htmtest=bye; Secure;Cookie is overridden
Cookie only used on HTTPS
Cookie is overridden
Cookie only used on HTTPS
test=helloworld; http://mydomain.com/hello/world.htmtest=bye; Secure;COOKIE IS OVERRIDDEN!
Cookie only used on HTTPS
Cookie is retained
test=helloworld; Secure;http://mydomain.com/hello/world.htmtest=bye; SecureCOOKIE IS OVERRIDDEN!
Cookie only used on HTTPS
Cookie is retained

Now you'd think that the browser wouldn't accept any cookies marked as Secure over an insecure connection, because that is a security vulnerability. The more recent browsers seem to have fixed that.

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.

Test case 18 - Basics

https://v8.prnx.net/hello/set-secure1.asp
https://v8.prnx.net/hello/secure1.asp
http://v8.prnx.net/hello/secure1.asp

Test case 19 - Nonsecure override

https://v8.prnx.net/hello/set-secure1.asp
https://v8.prnx.net/hello/set-nonsecure1a.asp
https://v8.prnx.net/hello/secure1.asp
https://v8.prnx.net/hello/set-secure1.asp
http://v8.prnx.net/hello/set-nonsecure1b.asp
https://v8.prnx.net/hello/secure1.asp

Test case 20 - Secure override

http://v8.prnx.net/hello/set-nonsecure2a.asp
https://v8.prnx.net/hello/set-secure2a.asp
https://v8.prnx.net/hello/secure2a.asp
http://v8.prnx.net/hello/set-nonsecure2b.asp
http://v8.prnx.net/hello/set-secure2b.asp
https://v8.prnx.net/hello/secure2b.asp
https://v8.prnx.net/hello/set-secure2c1.asp
http://v8.prnx.net/hello/set-secure2c2.asp
https://v8.prnx.net/hello/secure2c.asp

Effects of __Secure- and __Host- prefixes

Instead of fixing the insecure behaviors in the web browsers some genius thought: why not slap on another standard?!
Here is a link to the Cookie Prefixes standard

A cookie who's name is prefixed with __Secure- cannot be set over/from an HTTP connection.

  Set-Cookie: __Secure-test=helloworld; Secure;

In the example, the cookie __Secure-test cannot be overriden from/over an HTTP page.

The table shows for each brand of web browser if the cookie set be set from/over HTTP when the __Secure- prefix is used.

Requested page Set-Cookie header Safari 5,
Safari 10,
Internet Explorer 11,
Edge 40
FireFox 56,
FireFox 58,
Chrome 64
https://mydomain.com/hello/world.htm__Secure-test=bye;ACCEPTEDNot accepted
https://mydomain.com/hello/world.htm__Secure-test=bye; Secure;AcceptedAccepted
http://mydomain.com/hello/world.htm__Secure-test=bye;ACCEPTEDNot accepted
http://mydomain.com/hello/world.htm__Secure-test=bye; Secure;ACCEPTEDNot accepted

As you can see, the web browser that support the __Secure- prefix have all fixed thei SECURE property handling. In other words, the __Secure- prefix effectively adds no addition protection. It only protects against inadvertently forgetting the SECURE property.

And there is a caveat to using cookie prefixes. Because it requires the server to block/abandon cookies with encoded characters in them. For example, a cookie like %5F%5FSecure%2Dtest is not protected, but the server may interpret it as __Secure-test, thereby circumventing the protection.

Test case 21

https://v8.prnx.net/hello/set-secureprefix1.asp
https://v8.prnx.net/hello/secureprefix.asp
https://v8.prnx.net/hello/set-secureprefix2.asp
https://v8.prnx.net/hello/secureprefix.asp
http://v8.prnx.net/hello/set-secureprefix3.asp
http://v8.prnx.net/hello/secureprefix.asp
http://v8.prnx.net/hello/set-secureprefix4.asp
https://v8.prnx.net/hello/secureprefix.asp

A cookie who's name is prefixed with __Host- cannot be set from a subdomain. In addition to that, it includes the __Secure- functionality.

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

In the example, the cookie __Host-test cannot be overriden from a subdomain such as www.mydomain.com.

The table shows for each brand of web browser if the cookie set be set when the __Host- prefix is used.

Requested page Set-Cookie header Safari 5,
Safari 10,
Internet Explorer 11,
Edge 40
FireFox 56,
FireFox 58,
Chrome 64
https://mydomain.com/hello/world.htm__Host-test=bye; SecureAcceptedAccepted
https://www.mydomain.com/hello/world.htm__Host-test=bye; domain=.mydomain.com; SecureACCEPTEDNot accepted

No surpises here.

The same gotcha applies for all cookie prefixes. See remark below __Security- prefix.

Test case 22

https://prnx.net/hello/set-hostprefix1a.asp
https://v8.prnx.net/hello/set-hostprefix1b.asp
https://v8.prnx.net/hello/hostprefix.asp
https://prnx.net/hello/hostprefix.asp

Exceptions

A HTTP response can have multiple Set-Cookie headers. However, it should only have a maximum of one header per combination of cookie name, domain and path. So what happens if the server does not comply with this specification?

  Set-Cookie: test=none;
  Set-Cookie: test=expires;  expires=Thu, 22-Jan-2015 00:00:10 GMT
  Set-Cookie: test=maxage; Max-Age=900

In the example, each of the three Set-Cookie headers is about the same cookie name/domain/path combination. In other words, they are each about the same cookie.

The table shows for each brand of web browser how it handles undefined situations.

Set-Cookie headersSafari 5,
Chrome 39,
Internet Explorer 11,
FireFox 34
Set-Cookie: test=none;
Set-Cookie: test=expires; expires=Thu, 22-Jan-2015 00:00:10 GMT
Last header is executed / value="expires"
Set-Cookie: test=expires; expires=Thu, 22-Jan-2015 00:00:10 GMT
Set-Cookie: test=maxage; Max-Age=900
Last header is executed / value="maxage"
Set-Cookie: test=maxage; Max-Age=900
Set-Cookie: test=none;
Last header is executed / value="none"
Set-Cookie: test=none;
Set-Cookie: test=httponly; HttpOnly;
Last header is executed / HttpOnly
Set-Cookie: test=httponly; HttpOnly;
Set-Cookie: test=secure; Secure;
Last header is executed / Secure
Set-Cookie: test=secure; Secure;
Set-Cookie: test=none
Last header is executed / value="none"
Set-Cookie: test=none
Set-Cookie: test=expired; expires=Thu, 01-Jan-1970 00:00:10 GMT
Last header is executed / cookie removed

So no surprises here.

To be continued, with topics like how 3rd party cookies are handled, etc.

Mail your comments to gertjans@xs4all.nl.