Security Tip: What Is An HttpOnly Cookie?

[Tip #86] Cookies come in many shapes and sizes, and with multiple attributes just to confuse you... Have you ever wondered what the humble HttpOnly attribute actually does?

Security Tip: What Is An HttpOnly Cookie?

Cookies are a fundamental part of the internet, especially for PHP and Laravel developers like ourselves. Without them, we wouldn't have authenticated sessions that persist across page refreshes, or remember me tokens to avoid logging in every day. (We also wouldn't have Cross-Site Request Forgery (CSRF) tokens, or a need for them, but that's another topic!)

Since cookies are so fundamental to what we do and Laravel basically handles them for us, it's easy to completely overlook how they work and the different options available. So with this in mind, let's take a look at one of the features, or attributes, of cookies: HttpOnly.

The HttpOnly cookie attribute instructs the browser to prevent javascript from accessing that cookie. The cookie will still be sent to the server, but the javascript has no way to access it, preventing XSS attacks (and 3rd party scripts) from stealing those cookies.

This is especially important to Authentication and Remember Me cookies, as these values allow anyone who possesses them to be logged in as the user. If an XSS attack can steal a user's Authentication cookie, they'll get access to the user's account.

If we take a look in Laravel's default config/session.php file, we'll see this option near the bottom:

/*
|--------------------------------------------------------------------------
| HTTP Access Only
|--------------------------------------------------------------------------
|
| Setting this value to true will prevent JavaScript from accessing the
| value of the cookie and the cookie will only be accessible through
| the HTTP protocol. It's unlikely you should disable this option.
|
*/

'http_only' => env('SESSION_HTTP_ONLY', true),

Laravel defaults to HttpOnly on its session cookies, and unless you're doing something very specific (and have other controls in place), you'll want to keep this enabled.

💡
Note that this setting only applies to Laravel's session cookie (*_session). The 'remember me' cookie (remember_web_*), and any custom cookies you create will inherit the Laravel (and Symfony) default of HttpOnly=true. You'll need to override this when configuring your cookie to disable it.

I see this question a lot, so I wanted to address it quickly here. If we take a look at a set of cookies from a standard Laravel app:

Cookies from Laravel Forge.

You'll notice that while both larave_session and remember_web_* have HttpOnly set, the XSRF-TOKEN cookie is left without HttpOnly, allowing javascript to access it directly. This is by-design.

The XSRF-TOKEN cookie is a method of providing your CSRF token to javascript toolkits, so they can automatically detect and include it in any requests they make back to your site - avoiding the need for you to manually handle it in tour code yourself.


If you've made it this far, please share this Security Tip and Securing Laravel with your Laravel friends, colleagues, and enemies! The more folks we have learning about security, the more secure code will be written, and the safer the whole community and our users will be. Also, if you tag me I'll give it a retweet.

Find me on: Pinkary, Twitter, Mastodon, LinkedIn, & Threads.