The reason why cookies do not work with a heroku.app domain name
One of the projects I created for my portfolio during my learning journey was Sea Turtle Charter. The front-end is a very basic Next.js web application hosted on Vercel. The back-end is a Node/Express API hosted on Heroku with a PostgreSQL database.
As the front-end and back-end were hosted on two entirely separate platforms and domains, it forced me to learn a lot about web security. Here is a list of some of the issues I encountered and handled while working on this project:
- CORS
- Pre-flight requests
- CSRF through double cookie submit pattern
- Secure sessions through cookies
- SQL injection protection
- Rate limiting on login page
- Various request headers
- Hashing passwords for storage
One issue I encountered was the inability of my Heroku app to set cookies on my herokuapp.com
back-end.
If you have ever dealt with a separate front-end and back-end you know that any number of causes can cause issues with cookies.
As a result, it took me a while to figure out exactly what was causing the issue. Finally, I discovered that herokuapp.com
is included in Mozilla's Public Suffix List.
Overview
In this article I will discuss the Mozilla Public Suffix List
, why it exists, and how you can solve this issue with your web
applications. This issue typically only affects the free domain names you receive from platforms as a service such as Heroku.
The majority of users using these free domain names are beginners that are most likely not aware of the Mozilla Public Suffix
List. Hopefully this article can help other web developers understand the issue and how to solve it.
This issue does not just affect Heroku. It affects other platforms as a service such as Vercel and Netlify.
Table of Contents
- How cookies are scoped?
- What is Mozilla's Public Suffix List?
- How to avoid cookie issues with Heroku
- Learn more
How cookies are scoped?
Under normal operation, a website can set a cookie that is scoped to its domain or to any higher level DNS domain it belongs to.
This process is dictated by the cookie's domain
attribute which is included in the Set-Cookie HTTP response header.
For example let's pretend that you are on https://www.billy.bob.com/
and you are setting a cookie. You could create a cookie
with the following levels of scope:
- Just
https://www.billy.bob.com/
- All hosts ending in
billy.bob.com
such asappointment.billy.bob.com
- All hosts ending in
bob.com
such asthomas.bob.com
This capability is allowed as typically a single entity has complete control of the bob.com
domain. Not allowing cookies to be
passed between any host ending in bob.com
would make your jobs as web developers extremely difficult.
This cookie could not be passed to www.flyingbikes.com
. This is because .com
, .edu
, .org
, etc are considered Top-Level
Domains (TLDs). Cookies cannot be scoped to a Top-Level Domain as this would be a serious security flaw. Anybody could own the
flyingbikes.com
domain and naturally you would not want your session cookie from billy.bob.com
to be passed to a domain
with an unknown owner.
What is Mozilla's Public Suffix List?
This is where the Mozilla's Public Suffix List
becomes useful. With the rise of platforms as a service, there were many
different web applications belonging to many different users that were all registered under heroku.app.com
.
Since heroku.app.com
is not a TLD, a user could theoretically set a cookie that can be retransmitted to all hosts ending
in heroku.app.com
. This means that cookies could be getting passed around between thousands of web applications. Clearly this
is a huge security flaw.
As a result, a group of volunteers at Mozilla has created the Public Suffix List
. This is a list of domains that cookies cannot
be shared across. The full list can be seen here.
heroku.app.com
is included on this list which is why web applications hosted on Heroku cannot set cookies to a heroku.app.com
domain. Other platforms as a service such as Vercel are included on this list.
This list significantly increases cookie security. All major browsers abide by this list and even use the list for other features. If you would like to learn more, Mozilla's documentation has more information.
How to avoid cookie issues with Heroku
The solution to this issue is very straightforward. You need to add a custom domain to your web application. Your custom domain
will not be included on the Public Suffix List
and as a result you will be able to set your cookies properly.
If you would like to learn more about using Google Domains with Heroku check out this article.
Learn more
This is a very common issue with a simple solution. Hopefully this article helped to minimize the time and energy you spent troubleshooting why your cookies were not being set.
If you would like to learn more about the Mozilla Public Suffix List
, these resources are a great place to start: