# Secure the Cookie!

- Link: https://www.agilicus.com/secure-the-cookie/
- Published: 2020-06-02T00:06:49+00:00
- Author: Don Bowman

Cookies are a method by which a web server can convince a web client to remember,
and return, some information. It’s technically a violation of the web since the 
HTTP protocol is intended to be idempotent. Some also consider it a violation of
privacy.

However, in this video we are not going to take a position on the good/bad/ugly 
of cookies. Instead we are going to focus on how to use them securely.

First, let’s understand how long it will live. Cookies have a `expires` and `max-
age` attribute. If you set either of these (to some time in the future), the cookie
will survive a browser restart (a persistent cookie). If you don’t set it, it becomes
a session cookie.

So, we’ve just learned our first lesson: the more sensitive the data, the shorter
the expiry should be to limit the damage.

Second, let’s learn about the `secure` flag. How great is it to make security be
a Boolean! Well, it’s not that great here. The Secure flag means ‘do not send unencrypted’(
in practise, only send over HTTPS). So we’ve learned our second lesson: always use
Secure. No excuses!

Third, let’s talk about the httpOnly flag. Well this is a weird one, its all HTTP
right? Well, it turns out they mean more HTML-only. If httpOnly is set, we cannot
read the cookie from JavaScript. You want this, it prevents Cross-Site-Scripting(
XSS) type attacks where rogue JavaScript snoops around. If you have JavaScript that
needs to read cookies, maybe try and solve that. Now, the httpOnly flag is not an
absolute, there is a type of attack called Cross-Site-Tracing (XST). Purists will
tell you to disable the TRACE method on your web server.

Not content w/ httpOnly and Secure, the cookie committee created the SameSite flag.
Sometimes called First-Party cookies it allows a server to reduce the impact of 
a Cross-Site Request Forgery (CSRF) attack by forcing a cookie to only be sent with
requests from the same domain. Not universally implemented, somewhat newer, support
is still strong. Do your best to set this to ‘strict’. If you find that your POST
fail, and you cannot fix your application, have a long discussion with yourself 
about `lax`.

OK, that must be it, right. Wait, there’s more? The HostOnly flag specifies if a
cookie can be used on subdomains. If you are doing single-sign-on across multiple
sites, you want this set to the domain. For individual web applications, you likely
want the domain field blank. A cookie with a domain attribute controls where it 
will be sent.

Seem complex? Just do this:

 * Don’t use cookies unless you must
 * Don’t set expiry, or use a very short one
 * Use httpOnly always
 * Use Secure always
 * Use SameSite strict unless you can’t
 * Leave domain empty unless used for single sign on

If you want to see an example of how you could use Lua OpenResty, a Web Application
Firewall, to add some after-the-fact-security, have a look below!

    ```wp-block-preformatted
    local headers = ngx.req.get_headers()
    if headers["x-forwarded-proto"] == "https" then
      local ck = require "resty.cookie"
      local cookie, err = ck:new()
      local fields, err = cookie:get_all()
      if fields then
        for k, v in pairs(fields) do 
          local ok, err = cookie:set({ 
            key = k, 
            value = v, 
            path = "/", 
            httponly = true, 
            secure = true, 
            samesite = "Strict" }) 
        end
      end
    end
    ```
