Part 4 - Cookie Attribute Domain
In Part 3, we discussed how the 2 attributes, Expires
and Max-Age
, alter how long a browser will store your cookies.
In this post we’ll talk about how the Domain
attribute changes which domains the browser will share your cookie with.
Domain
By default, a browser will only send cookies to the specific domain that set the cookie - not any of its subdomains. This is generally the more secure option.
If you want the browser to share your cookie with a specific domain and all of its subdomains, you can set the Domain
attribute like so:
Set-Cookie: cookieName=cookieValue; Domain=example.com;
In this example, we set the cookie from example.com
. The browser will now attach the cookie to all requests for example.com
and its subdomains, such as:
blog.example.com
admin.example.com
reports.admin.example.com
Note: Setting the attribute as domain=example.com
or domain=.example.com
is considered identical and acts the same.
Now, if you wanted the cookie to be sent to a specific subdomain instead, such as blog.example.com
, and all of its subdomains, (like test.blog.example.com
), you would set it like this:
Set-Cookie: cookieName=cookieValue; Domain=blog.example.com;
Security concerns
Warning! Subdomains are an attack vector and should not be implicitly trusted. By setting the Domain
value, you are making your cookie less secure.
For example, let’s say an attacker can run code on your subdomain test.example.com
using a Cross-Site Scripting (XSS) attack.
You set your log in cookie with the site declared as the domain, like so:
Set-Cookie: authorized=LargeRandomNonce; Domain=example.com;
This cookie will now be shared with all the subdomains for that site. If an attacker can trick a logged in user to visit the subdomain they control (test.example.com
), that user’s cookie will be shared with the attacker. They can then use that cookie to gain access to the user’s account. Not ideal.
If you’d like to keep your cookies more secure and prevent them from being shared between subdomains, you should NOT set the Domain
attribute.
Note: If you host user content, instead of using subdomains, consider moving user hosted content to a different domain. For example, GitHub allows you to host your own website, but not using github.com
. All user content is hosted on github.io
- a completely different site. This helps GitHub avoid having untrusted user content available on their main domain and reduces the likelihood of subdomain attacks.
Can I set the domain from a subdomain to a higher level domain?
For example, can I set Domain=account.example.com
from login.example.com
?
No, because the site you are specifying (account.example.com
) does not include the origin server.
What’s an origin server?
The origin server is the scheme (protocol), hostname (domain), and port of the URL this request was sent to.
You can’t set the Domain
for a different subdomain from a non-inherited subdomain because they do not share an origin.
For example, let’s say a user logs in on your subdomain - https://login.example.com
. The origin server would be https://login.example.com:443
(where the port is implied by the HTTPS
protocol).
But you want to set the cookie so it can only be used on a different subdomain - account.example.com
.
If you were to set Domain=account.example.com
, the browser would just ignore the cookie and not store it. Why? Because account.example.com
is not included in the origin server - https://login.example.com:443
.
You’d have to set Domain=example.com
, then it can be accessed by ALL the subdomains of that site, which is a potential security risk. But you can’t directly set the Domain
for a subdomain from a different subdomain.
Can I set a cookie for someone else’s domain?
You can try, but it won’t work.
If you set a cookie from your web server, let’s pretend it’s at https://example.com
, but declare the domain to be Yahoo, like this:
Set-Cookie: cookieName=cookieValue; Domain=yahoo.com;
The browser will just ignore your cookie and not store it. Why? Because yahoo.com
is not part of the origin server - https://example.com:443
.
Next: Read Part 5 - Cookie Attribute: Path