Secure Cookies with Laravel

Feb 24, 2022 by Zacharia | 783 views

Secure Software Development Laravel PHP

https://cylab.be/blog/203/secure-cookies-with-laravel

No. Setting HTTPS is not enough to ensure that your cookies are encrypted. But Laravel proposes some very simple ways to achieve that.

photo-1422207239328-29f83832206c.png

As stated by OWASP, the cookie secure attribute is necessary to ensure that a cookie is sent over a secure connection (HTTPS) only. If it is sent over HTTP, the cookie is in clear text and therefore its content can be read by anyone who is able to observe your online activity. The secure attribute is a value in the cookie structure that has to be set to true in order to ensure that the cookie is encrypted over HTTPS requests only.

Laravel Cookies

Modern versions of Laravel (tested with Laravel 8+) offers two simple ways to add that secure attribute to your cookies. Before showing how to do it, let's discuss about the two types of cookie considered by Laravel:

  • Session & XSRF-TOKEN cookies:
    • the Session cookie is used to identify the session of a user who previously successfully authenticated and its purpose is storing information about a user across multiple requests, a necessity since HTTP applications are stateless;
    • the XSRF-TOKEN is sent along requests to counter Cross-site Request Forgery (XSRF) attacks.
  • Custom cookies: these are all the cookies you added (language, consent...) and their purpose is to track or ease the use of your website by adapting the experience of each user to their actions.

Securing Session and XSRF-TOKEN Cookies

Securing Session and XSRF-TOKEN cookies can be done with the following steps:

  1. Declare the value of the SESSION_SECURE_COOKIE environment variable as true in your (production) .env file:
    SESSION_SECURE_COOKIE=true
  2. In the config/session.php file, look for the 'secure' key and set it to the value of your previously defined SESSION_SECURE_COOKIE variable:
    'secure' => env('SESSION_SECURE_COOKIE', true),

Tip: if your deployment uses Kubernetes, you probably use a deployment file (e.g. deploy.tmpl). If that is the case, you need to define your environment variable in that file too. It will be present in the data of your ConfigMap:

SESSION_SECURE_COOKIE: "true"

Securing your Custom Cookies

That is even easier ! In fact, you have nothing to do. When you activated the secure session, which is what we did in the previous section, then all your cookies are encrypted by default. Indeed, the file app/Http/Middleware/EncryptCookies.php is a middleware that gives you the possibility to choose the cookies you don't want to be encrypted:

<?php

namespace App\Http\Middleware;

use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;

class EncryptCookies extends Middleware
{
    /**
     * The names of the cookies that should not be encrypted.
     *
     * @var array
     */
    protected $except = [

    ];
}

That middleware is called for each request since it is placed in the app/Http/Kernel.php file:

/**
 * The application's route middleware groups.
 *
 * @var array
 */
protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        ...,
    ],
    ...,
];

Remarks

  1. Custom cookies will only be encrypted when HTTPS is used, which is logical since that is the whole purpose of the secure attribute. Here is the message shown in the Firefox console when you try to encrypt cookies over an HTTP connection:

    secure_but_http.png

  2. In the Firefox Developer Mode, in the Storage tab, you can see the value of the cookies before and after setting the secure attribute:

    Before: secure_false.png

    After: secure_true.png

Your cookies are now secured!