Security Tip: Auto-Secure Cookies FTW! π
[Tip #92] One of my personal pet peeves in Laravel has finally been fixed! The Secure cookie attribute will now match the request protocol! π (I'm excited, can you tell?)
Three years ago in Security Tip #5: The Cookie βSecureβ Flag, I talked about the Secure
attribute for cookies. Since you should always have Secure
set on your cookies (when you use HTTPS, which we all do... right?) to keep your cookies safe, it was my recommendation back then to update your config/session.php
to enable Secure
by default, and override it in local dev when you're not using HTTPS. This prevents you from forgetting to set it in production.
Secure
cookie attribute tells the browser that the cookie can only be sent back to the server on a encrypted https://
connection. This prevents cookies from being sent over unencrypted http://
requests, such as during Person in the Middle (PitM) or downgrade attacks where the entire request (including any cookies) may be captured by a malicious third party.Since then, I've done numerous security audits and cookies missing the Secure
flag missing is still high up there on common issues I've flagged. There have been a few attempts over the years to update the default, or even get SESSION_SECURE_COOKIE
into .env.example
, but none have succeeded. π
However, I am now pleased to report that thanks to efforts of Fabrice Locher, it is no longer needed, and my days of reporting it on virtually every site I audit are (hopefully) coming to an end! π
In a PR from the 8th August, Fabrice did some digging into the underlying Symfony cookie system and discovered Symfony already toggled the Secure
attribute based on the current request's protocol (i.e. http://
vs https://
), and realised that enabling support for this feature in Laravel was just a single line change! π²
Here is the entire commit:
When this is combined with Laravel's default configuration:
We get the following behaviour in a fresh Laravel installation...
When accessed over http://
, the laravel_session
cookie does not have Secure
set:
When I enable HTTPS and access the site again over https://
, the laravel_session
cookie has Secure
set:
There were no config changes, all I did was toggle "HTTPS" in Herd and refresh the page! π
This means we no longer need to toggle this setting on or off depending on what environment we're working in, and as a pentester, this makes me so incredibly happy!
Frameworks like Laravel should be secure by default, and anything that can be done to automatically enable security features without impacting developer or user experience is a huge win. This is one less finding I'll be reporting for my clients (when they've upgraded to Laravel 11!), and one less potential avenue to attack hackers have against Laravel in general.
Huge thanks to Fabrice Locher for finding and fixing one of my personal pet peeves in Laravel!
Found this security tip helpful? Don't forget to subscribe to receive new Security Tips each week, and upgrade to a premium subscription to receive monthly In Depth articles, or toss a coin in the tip jar.
Reach out if you're looking for a Laravel Security Audit and Penetration Test or a budget-friendly Security Review, and find me on the various socials through Pinkary. Finally, don't forget to check out Practical Laravel Security, my interactive security course.