HTTPS secures the communication channel against eavesdropping: that is, any man-in-the-middle who could otherwise read your traffic without either side noticing will now see nothing but encrypted data, and the encryption is done in a way that it can only be undone either by getting at the server's private key, or by attacking the encryption algorithm itself. Additionally, HTTPS makes sure that the server you're talking to is actually the correct one: the certificate specifically points to a domain name (e.g. acme.com
), and the server authenticates itself through the certificate; this way, when someone hijacks your DNS and points acme.com
to their own server, they won't have a valid certificate to serve, and the authentication will fail (this is what happens when your browser throws a huge warning sign in your face).
Now, when you log into a website, the server has to know who you are on subsequent requests, and the way this is usually (well, practically always) done is through a session cookie. This cookie is set once at login, and then sent back to the server on every request. Now consider what happens when such a request is not encrypted: an eavesdropper can read it, including the Cookie
header, extract the cookie, and take over your login. You don't want that.
Technically speaking, only sensitive requests have to contain the cookie and run over a secure connection, but mixing secure and non-secure requests within one document leads to a whole cornucopia of other issues, and it's just too difficult to get right that the general consensus is that it's better (easier and more reliable) to just serve everything over HTTPS, including scripts, images, stylesheets, AJAX requests, and anything else you can think of.
Another thing to keep in mind: The Cookie RFC specifies two flags you can set on a cookie: SECURE
and HTTP_ONLY
. For session cookies, you should always set both, and here's why:
SECURE
instructs the browser to never send the cookie over an insecure connection. When you set it, an attacker won't be able to trick the browser into sending it over an untrusted (and potentially hijacked) connection, which removes an entire class of attack angles from the scene. Similarly, if you missed a spot and your application accidentally sends plain HTTP requests from an HTTPS context, an eavesdropper might still see the cookie without this flag, but with it, the browser will simply silently exclude the cookie from the request. Not all browsers honor this flag, so you still need all the other precautions, but the recent mainstream ones all do.
HTTP_ONLY
means the cookie is not accessible from within JavaScript, not even read-only. This prevents combinations of XSS and Session Hijacking attacks, where an attacker uses XSS to plant JavaScript which then reads the session cookie and sends it back home. With the HTTP_ONLY
flag, the cookie will be invisible to the JavaScript, so the attack won't work.