Security Tip: The Cookie ‘Secure’ Flag

[Tip#5] Don't forget to configure your cookies for to only work over HTTPS.

Security Tip: The Cookie ‘Secure’ Flag

👉 Looking to dive deeper into Laravel security? Check out Practical Laravel Security, my hands-on security course that uses interactive hacking challenges to teach you about how vulnerabilities work, so you can avoid them in your own code! 🕵️

Worried about your app being hacked? Book in a Laravel Security Audit and Penetration Test! I can find the vulnerabilities before a hacker does, and help you fix them! 🕵️


There are multiple flags that can be set on browser cookies, but the one we’re talking about today is the `Secure` flag. This flag instructs the browser to only accept the cookie if the connection is considered secure, i.e. over HTTPS. If you visit the site over HTTP, the browser will not send or receive any cookies with the flag set.

This is important for security as HTTP requests are not encrypted. If someone can monitor the connection between you and the server, they can read all of the contents of the request and response. This includes your cookies, and if these include a session token, they can hijack your account.

This attack was exploited by a Firefox extension called Firesheep back in 2010, which monitored the network you were connected to and stole any usable session cookies to popular social media sites. When it first came out, this plugin was very popular on free public wifi, for obvious reasons!

This video provides a great demo of it in action:

The Solution

The solution is simple, set the `session.secure` config value to be `true` on production and use `https://` exclusively. This will fully protect your cookies from this attack, as they will never be sent over an unencrypted connection.

Laravel even provides an env var for it by default, `SESSION_SECURE_COOKIE`, but it annoyingly doesn’t set a default and leaves it out of the `.env.example` file.

I recommend you update the `./config/session.php` file in your apps to default to true, like this:

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

And then add it into your `.env.example` file as a commented out option:

SESSION_DRIVER=file
SESSION_LIFETIME=120
#SESSION_SECURE_COOKIE=true

This ensures that your deployed apps will have the secure flag set by default, while also providing your developers with a simple way to disable the flag if they use HTTP for local development.

It’s the best of both words and will keep your cookies secure.