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?)

Security Tip: Auto-Secure Cookies FTW! πŸŽ‰

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.

πŸ€“
The 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:

A single line was changed from `$config['secure'] ?? false,` to ` $config['secure'],`.
Single line change to enable automatic Secure cookies.

When this is combined with Laravel's default configuration:

'secure' => env('SESSION_SECURE_COOKIE'),

config/session.php

We get the following behaviour in a fresh Laravel installation...

When accessed over http://, the laravel_session cookie does not have Secure set:

Screenshot of the Laravel default screen, on a http:// URL, showing cookies without Secure set.

When I enable HTTPS and access the site again over https://, the laravel_session cookie has Secure set:

Screenshot of the Laravel default screen, on a https:// URL, showing cookies with 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.