Web Security

Secure, HttpOnly, SameSite: Cookie Attributes Explained by What Goes Wrong Without Them

Three attributes, three specific attacks. What each one stops, what happens on the day it is missing, and the one line of Set-Cookie a session cookie should carry.

Webcuris Research

Security Engineering

·2 min read

Set-Cookie: session=…; Secure; HttpOnly; SameSite=Lax

A session cookie is a bearer token: whoever holds it is the user. Three attributes decide how hard it is to take one, and each maps to a specific attack rather than to general good practice. Read them that way and the configuration stops being a checklist item.

what a session cookie should look likehttp
Set-Cookie: session=…; Secure; HttpOnly; SameSite=Lax; Path=/

Without Secure, the browser attaches the cookie to any request to your domain, including plaintext HTTP. One http:// link, one typed address before the redirect, one asset reference someone forgot to update — and the session travels in the clear past anyone on the network path. Your HTTPS redirect does not save you: the cookie is on the request that gets redirected.

It pairs naturally with HSTS, which removes the plaintext request entirely. Secure is the belt; HSTS is the braces, and both are one line.

HttpOnly — stops JavaScript reading it

This is the attribute that decides how bad your next XSS is. With HttpOnly, injected script cannot read document.cookie, so a script bug stays a script bug. Without it, the same injection reads the session token and posts it elsewhere — and the attacker no longer needs your page at all, because they have the user. The difference between those two outcomes is one word in a header.

SameSite — stops other sites spending your session

SameSite controls whether the cookie rides along on requests originating from other sites. Without it, a form on attacker.example can POST to your endpoint and the browser helpfully attaches the victim's session — cross-site request forgery. The values differ in how strictly they refuse:

ValueSent cross-site?What it costs you
StrictNeverA user following a link from email or another site arrives logged out — often surprising
LaxOnly on top-level GET navigationsThe sensible default: links work, cross-site POSTs do not
NoneAlways — and requires SecureOnly for cookies that genuinely must work in a third-party context, e.g. an embedded widget
Modern browsers treat a cookie with no SameSite as Lax, but relying on that default means the behaviour is the browser's decision rather than yours.

Check what your site actually sends

read the attributes on every cookie you setbash
curl -sI https://example.com | grep -i set-cookie

Read each line attribute by attribute. The common failure is not a site with no attributes anywhere — it is a site where the session cookie is correct and an auxiliary one is not, or where a framework default was overridden in one code path. This is one of the checks in reading all your security headers, and it is worth doing per cookie rather than per site.

Then keep it true. Cookie attributes are set in application code, which means they regress the way code regresses — a refactor, a new endpoint, a library upgrade that changes a default. A free scan reads the attributes on every cookie your site sets, and monitoring tells you the day one of them drops.

Get the next one

One email when a new article goes out. No newsletter, no drip sequence, no sales follow-up.

Unsubscribe in one click. We never sell or share the address.

Keep reading

Contact

Talk to us.

Questions about what the engine checks, whether it fits your estate, or what it deliberately refuses to do. A person reads every message.

  1. 01You writePlain form, no qualifying call, no obligation. The marketing checkbox is optional and unticked.
  2. 02A person reads itMessages land with the team, not a queue-bot. Nothing is auto-replied.
  3. 03You get an answerTo the address you gave — including “this product is not the right fit”, when that is the honest answer.
Reporting a vulnerability?
Read the disclosure policy first — it tells you what is in scope and what to expect.
New messagereplies go to your email

We reply to this address, so a disposable one will not reach you.

+91

0 / 4000