Skip to main content
Ben Nadel at Scotch On The Rock (SOTR) 2010 (London) with: Roman Schlaepfer
Ben Nadel at Scotch On The Rock (SOTR) 2010 (London) with: Roman Schlaepfer@appleseedexm )

Leading Dots On HTTP Cookie Domains Ignored

By on
Tags:

I've been using Cookies in my ColdFusion web applications forever. But, I honestly don't have the best mental model for how the low-level intricacies of cookies work. For most of my career, I only ever defined cookies using a "name", "value", and an "expires" attributes — I didn't even know you could define a "domain" until we had to start locking down enterprise-cookies (by subdomain) at InVision. And even now, I'm still fuzzy on how the domain setting operates; which is why something caught my eye when I was reading through the Set-Cookie HTTP header docs on MDN:

Domain=<domain-value>

Defines the host to which the cookie will be sent. If omitted, this attribute defaults to the host of the current document URL, not including subdomains. Contrary to earlier specifications, leading dots in domain names (.example.com) are ignored. Multiple host/domain values are not allowed, but if a domain is specified, then subdomains are always included.

At work, we definitely have code that sets and expires cookies using a leading dot (.); but, it seems like this appendage may be superfluous. To test this, I wanted to look at whether or not domains with-and-without a leading dot are interoperable.

First, I tried setting a cookie with a leading dot:

<cfscript>

	// Using a leading-dot on the cookie domain to STORE the cookie.
	cookie[ "hello" ] = {
		domain: ".local.invisionapp.com",
		value: "world",
		preserveCase: true,
		expires: "never"
	};

</cfscript>

And, when we run this Luce CFML / ColdFusion code, we can see that the cookie is set:

EditThisCookie Chrome extension showing cookie domain set with leading dot.

As you can see, the domain in my EditThisCookie Chrome extension show the leading dot. But now, let's try to delete (expire) this cookie using a domain with no leading dot:

<cfscript>

	// Using NO leading-dot on the cookie domain to DELETE the cookie.
	cookie[ "hello" ] = {
		domain: "local.invisionapp.com",
		value: "",
		preserveCase: true,
		expires: "now" // Expire the cookie.
	};

</cfscript>

Here, we're using the same domain, only we're omitting the leading dot. And, when we run this Lucee CFML / ColdFusion code, we can see that the cookie has been removed!

EditThisCookie Chrome extension showing cookie was removed even though we expired a cookie without a leading dot.

As you can see, the cookie was successfully evicted when we expired the cookie using a domain without a leading dot.

I also tried this in the other direction as well:

  1. Set the cookie without a leading dot.

  2. Expire the cookie with a leading dot.

And, the results are the same. The interoperability goes in both directions. Which makes sense if you take the MDN at their word: that the leading dot gets ignored.

It's somewhat ironic that cookies are such a fundamental part of how web applications work; and yet, after so many years, I'm still building out my mental model for how cookies interact with my ColdFusion applications.

Epilogue: No Domain != Full Domain

As I mentioned above, my historical use of cookies didn't include a domain at all. When the domain is omitted, the cookie is scoped to the host of the current URL. However, as I discovered in my testing, if I set a cookie without a domain:

<cfscript>

	// Using NO domain to STORE the cookie.
	cookie[ "hello" ] = {
		value: "world",
		preserveCase: true,
		expires: "never"
	};

</cfscript>

... this will show up in my EditThisCookie Chrome extension with the domain, projects.local.invisionapp.com. However, the domain will be slightly grayed-out. And, what I discovered is that I cannot expire this cookie with the full domain:

<cfscript>

	// CAUTION: This DOES NOT WORK GIVEN ABOVE COOKIE SET.

	// Using FULL DOMAIN on the cookie domain to DELETE the cookie.
	cookie[ "hello" ] = {
		domain: "projects.local.invisionapp.com",
		value: "",
		preserveCase: true,
		expires: "now" // Expire the cookie.
	};

</cfscript>

Here, I'm using the same domain that the cookie is associated with locally. However, the cookie continues to exist even after I run this ColdFusion code. Providing an explicit domain is not the same as providing no domain, even when the values appear to be the same in the local cookie repository.

Update: October 31, 2022

Over on a different Mozilla page for Using HTTP Cookies, the documentation states that if I exclude the Domain, then it is implicitly provided without the subdomain:

The Domain attribute specifies which hosts can receive a cookie. If unspecified, the attribute defaults to the same host that set the cookie, excluding subdomains. If Domain is specified, then subdomains are always included. Therefore, specifying Domain is less restrictive than omitting it. However, it can be helpful when subdomains need to share information about a user.

It took me a little while to wrap my head around what this language meant. After some trial-and-error in my Lucee CFML test server, I realize that it means that the cookie will show up for the current domain only - and will not be sent for any other variation of the subdomains at all. This is what the above paragraph means when it says that "specifying Domain is less restrictive", because when you do that, the cookie can show up across subdomain variations.

Want to use code from this post? Check out the license.

Reader Comments

15,329 Comments

Here's something interesting, in the Lucee Docs on CFCookie, it states that the dot is required:

Domain

Domain in which cookie is valid and to which cookie content can be sent from the user's system. By default, the cookie is only available to the server that set it. Use this attribute to make the cookie available to other servers.

Must start with a period. If the value is a subdomain, the valid domain is all domain names that end with this string. This attribute sets the available subdomains on the site upon which the cookie can be used.

Post A Comment — I'd Love To Hear From You!

Oops!
NEW: Some basic markdown formatting is now supported: bold, italic, blockquotes, lists, fenced code-blocks. Read more about markdown syntax »
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.