I think the Domain and Path attributes of cookies are the least understood aspects of session management and cookie security, but they are very important and in many cases could, if mishandled, open the door to session hijacking, XSS and other nefariousness.
What are Domain and Path Attributes?The Domain attribute is used to store the domain to which a cookie belongs. The cookie will only be presented to a server for that domain (i.e. .12robots.com) and any of its sub-domains (i.e. blog.12robots.com).
The Path attribute is used in conjunction with the Domain attribute to provide more granular control over when cookies are sent to the server. If the path attribute is set, for example to "/blog/", then the cookie will only be sent to the server for requests within the specified domain, only when in the "blog" folder or any of its sub-folders.
The Domain and Path attributes of a cookie are used to keep cookies with the applications to which they belong and to not pass those cookies to other applications. Here is an example:
Let's pretend that we have a website for ColdFusion bloggers. Let's call it awesomecoldfusionbloggers.com. We cater to the 6 or 7 ColdFusion developers out there that don't already have a blog. But seriously, we'll say we have a lot of users (100's). When a new user signs up from an account, they get a choice of domain name. They can either get,
I am going to sign up for an account with awesomecoldfusonbloggers.com, and I am going to opt for the subdomain option. So my new blog will be at:
To discuss this any further, we need to understand the default behavior of the Domain and Path attributes and ColdFusion cookies.
Cookie Default BehaviorWhen ColdFusion session management creates a session for your application, it sets a cookie in the client browser. This cookie (called a session token) is used to maintain session state during use of the application. This cookie will be passed back to the server on ever appropriate request to maintain that state.
The default behavior of ColdFusion is to set a cookie with the Domain attribute equal to the domain that is being used when the cookie is set. So, if I visit my awesomecoldfusionbloggers.com, and a cookie is set, then that cookie will have a domain=.awesomecoldfusionbloggers.com attribute. Then, when I browse to 12robots.awesomecoldfusionbloggers.com another session cookie will be set for that domain. So the next question is, when will that cookie be passed back to the server for use?
So this is great, and it exactly how it should work, unless you have special requirements. But when we start controlling our own cookies, this is not how our cookies will behave.
When you set your cookies manually, then when you set a cookie for .awesomecoldfusionbloggers.com, unless you explicitly set one for 12robots.awescomecoldfusionbloggers.com when the user visits there, and another for otherblog.awesomecoldfusionbloggers.com when the user visits there, then it will use the .awesomecoldfusionblogger.com token for all sites that are sub-domains of awesomecoldfusionbloggers.com. Hence, it will pass your users' session tokens to ALL of the blogs they visit within that site. So when someone sets up hacker.awesomecoldfusionbloggers.com as a site to harvest session tokens, they can then invite other bloggers to check out there new blog and start stealing session tokens.
The default behavior of ColdFusion is to set a cookie with the Path attribute equal to "/", regardless of what folder is in the URL when the cookie is set. This can be immediately dangerous for our bloggers who chose the URL format:
For a moment, let's say that I opted for that format instead. So now my blog is at:
Now let's say that I log in, make a few posts about my cat, maybe one about a brownie recipe, and so forth. Meanwhile, my hacker ex-girlfriend wants nothing more than to vandalize my new blog. She creates an account at awesomecoldfusionbloggers.com and ops for the same URL pattern. Here new blog is at:
Obviously she is a PHP developer.
Now, she sits and watches my feed. Once she sees a new blog post appear, she knows I am logged in. She messages me an invite to check out her new post on why ColdFusion is dead. Needless to say, I am pissed. So I browse over to her site and read some silly arguments about how a language which stands the test of time is antiquated and that because it is easy to use that it is too simple for "real programmers". So I leave a comment about how ColdFusion rulez!, and I go back to taking pictures of my cat for http://icanhascheezburger.com/.
Next thing I know, my posts start disappearing. There is a new post about how stupid my cat is. And WTF??, a "ColdFusion is Dead" post. I try to log in and my password has been changed.
How did I get pwn'd?
You may have figured it out already, but psycho-hose-beast and I were on the same domain, but in different folders. Because the default cookie sets the path attribute to "/" and because we are on the same domain, it submitted all of my cookies to the server when I made a request to view her blog. And one of my cookies was my session token.
Controlling the Domain and Path variablesThe moral of this story, beyond the obvious lesson of scorning women, is that when you are working in an environment where you are dealing with sub-domains and subfolders that contain different applications, or pieces of applications that require different cookies to be submitted, it is important to control your cookies. This goes for both session token cookies, and any other cookies you may use, for any purpose.
So how do we do that?
In a previous post, we looked at how to rewrite our session tokens to be HTTPOnly and SECURE, we can use the same technique to set the Domain and Path variables.
<cfheader name="Set-Cookie" value="CFID=#session.CFID#;domain=.awesomecoldfusionbloggers.com;path=/12robots/" />
<cfheader name="Set-Cookie" value="CFTOKEN=#session.CFTOKEN#;domain=.awesomecoldfusionbloggers.com;path=/12robots/" />
And for non-session-token cookies you can use the standard <cfcookie> tag:
<cfcookie name="myCookie" value="myValue" domain=".awesomecoldfusionbloggers.com" path="/12robots/" />
Notice that the domain value begins with a "." (dot). This seems to be necessary to work properly. I have tried, unsuccessfully, to make this work with http://localhost/.
Technically, we can use <cfcookie> in this way to rewrite our session tokens as well, but since <cfcookie> does not support the HTTPOnly flag, I recommend using <cfheader>