Cookies are omnipresent all over the web as they let publishers store data directly on the user's web browser. Especially used to identify the user session allowing the web server to recognize him all along his browsing, cookies usually contain sensitive data. You have to properly protect them.
The Set-Cookie HTTP header
As a reminder, a cookie is usually created on the web browser following the server response, in order to store a status, that will be transmitted over the next requests. To do this, the web server uses a Set-Cookie header in an HTTP response. Here is the syntax of such a header:
_Set-Cookie: =[; =] [; expires=][; domain=] [; path=][; secure][; HttpOnly]_
The cookie is identified by a name, associated to a value. A lifetime and/or an expiration date can be set. Note that if both attributes are set then the lifetime value (max-age) will prevail.
The web server can also define a path and a domain to be used for the cookie. These domain and path attributes allow to restrain its range… or extend it (by allowing its usage on any subdomain for example). As a consequence, one of the first best practice about Cookies security consists in handling properly their range.
The last 2 attributes, secure and HttpOnly are specifically dealing with security. Please note that they don't accept a value. Their presence only will imply the browser behavior towards the cookie.
Forbid to use a cookie user-side thanks to HttpOnly
A cookie can be placed and used by a web server, but also directly on the web browser via Javascript.
In an XSS breach case, an attacker could inject some Javascript, and potentially access to the cookies that, as a reminder, often contain sensitive information. First of all, it is obviously better to prevent the XSS breaches. Then you can avoid those weaknesses to be exploited by defining a Content Security Policy.
The “HttpOnly” flag blocks the cookies usage via Javascript: if an attacker succeeds in injecting some javascript despite all your precautions, he won't be able to access the cookies anyway. That will significantly limit the attack range.
Forbid to use a cookie without HTTPs thanks to the Secure flag
We regularly recommend it on this blog: your website should use HTTPs.
If you have already adopted this protocol and applied our previous advice, you may think that your cookies are protected as they are transmitted through a secure communication and as they can't be reached in Javascript. Unfortunately, a noticeable issue remains. What if a user comes to your website via HTTP, simply because he's typing your URL without mentioning “https://”?
This could also happen if your web page contains mixed content. Setting an HSTS (HTTP Strict Transport Security) header, that will enforce HTTPS usage for all the upcoming visits, will limit the risks related to the first scenario. But all the browsers do not support this header… Still, the first visit remains an issue. About the second scenario, the Content Security Policy can prevent from any mixed content risk with browsers that support “Upgrade Insecure Requests” policy.
Actually, only the secure attribute will let you forbid a cookie to be ever transmitted via simple HTTP. The interest of this flag is clearly mentioned in the RFC HTTP State Management Mechanism:
_Servers that require a higher level of security SHOULD use the Cookie and Set-Cookie headers only over a secure channel. When using cookies over a secure channel, servers SHOULD set the Secure attribute (see [Section 4.1.2.5](https://tools.ietf.org/html/rfc6265#section-4.1.2.5)) for every cookie. If a server does not set the Secure attribute, the protection provided by the secure channel will be largely moot._
Obviously, keep in mind that a cookie using this secure flag won't be sent in any case on the HTTP version of your website. So be careful if your website still has got both HTTPS and HTTP areas.
As a conclusion, feel free to give a try to Dareboost web page analysis tool. It will let you ensure that all of your cookies are secured, by checking if HttpOnly and secure are properly used:
Top comments (7)
There is now a draft SameSite attribute for cookies that is also worth setting to prevent CSRF attacks.
Totally! I was planning another article to follow up about this in a couple weeks. Thanks Neil.
Excellent!
Hi Damien, thanks for the article. In this phrase, do you mean “httpOnly” instead of “secure”:
"The “secure” flag blocks the cookies usage via Javascript"
?
Hi Giovanni,
Thanks for pointing that out, I've got it fixed!
That was fast, you are welcome!
Being fast is mandatory when working in the webperf field ;)