It's now possible to make your cookies more secure and be explicit about what sites you want to be able to read them.
So, I've been making most of the cookies I use have a same site policy of strict. My understanding was that this would mean that only my site would be able to read them, which is exactly what I wanted. Except, they were even stricter than I expected and caused an unexpected side effect that made our site unusable.
After making some changes to our login procedure the site got stuck in an endless redirect loop. This is what was happening:
- The user logs in successfully using a third party login provider and is redirected back to our site's home routing page.
- Routing page: The site reads the user's identity, gets their preferences and works out what section of the site they should start at. The site sets some strict cookies to store preferences and then redirects the user to that section.
- Section page: The site tries to read the preference cookies. The cookies have not been sent in the request so it looks like they've not been set. So, the site redirects them to the routing page so the preferences can be set. This redirect was put in place in case users were directed to the wrong page from the login provider. We are now in an endless loop between step 2 and 3.
As I stepped through and watched the requests and responses in Chrome's debug tools, the cookies were repeatedly set in the response, but the following request never came back with the cookies. Even more confusingly, if I hit the browser stop button and visited the routing page directly, the cookies were suddenly available. The problem did not seem to be with setting the cookies, but with reading them after a redirect.
Setting the cookie's same site policy to lax fixed the issue, but I wanted my cookies to be super secure and I couldn't work out what the problem was. The cookies were getting set, but the browser didn't seem to trust my site to send them back.
While investigating the issue and with much trial and error I discovered two important things.
- A strict cookie stored by the browser will not be sent in a request by the browser if the referrer is not the same site as the one that set the cookie.
- The referrer for a redirected request will be the page and site that initially started the first request initiated by the user. If a redirect leads to any number of other redirects the referrer will not change and all these redirected requests will have the referrer of the first request.
So, in my case, when the user is redirected away from the third party login site to my site; the referrer is the third party site. I am then able to set some strict cookies and redirect to a new page on my site. When the browser gets this redirect response it keeps the referrer from the original request. As the referrer is still the third party site it does not send the strict cookies. As the cookies are not set my site keeps trying to set them again as it thinks they've not been set.
Once I understood this I was able to change the user flow to avoid this. I decided to turn the automatic routing page into a manual one where the user decides what section to go to. The user now clicks a link to get there. As they click a link the referrer is now the page with that link on and the strict cookies are sent because the page and the referrer are from the same site.
You might not find yourself stuck in an endless loop because of this, but you might also be confused why the first page of your site is unable to read strict cookies from the user's last visit. I hope this writeup of my findings helps others who experience this issue. If you have any further insights into how to make best use of strict cookies please get in touch.