← All checks
SecurityTypical severity: Medium

Insecure Cookie Scanner

Detects cookies missing the Secure, HttpOnly or SameSite attributes that guard against theft and CSRF.

What it checks

This scanner inspects the cookies your site hands to the browser and checks whether they are missing the Secure, HttpOnly or SameSite attributes. These attributes limit how and when each cookie can be used. It only looks at the protection flags, not the cookie contents.

Why it matters

A session cookie without these attributes can be stolen by malicious scripts or travel unencrypted, letting someone impersonate your users. It also enables CSRF attacks where a third party acts on the user's behalf. In practice this can mean full account takeover.

How to fix it

When creating cookies, set Secure so they only travel over HTTPS, HttpOnly so JavaScript cannot read them, and SameSite (Lax or Strict) to limit cross-site use. Most frameworks and session libraries expose these options in their configuration. Pay special attention to your login or session cookie.

How this check works

Scanaris reads the Set-Cookie headers your server sends when loading the home page and reviews the attributes of each cookie. It checks three things: that it carries Secure (only required if the site is served over HTTPS), that it carries HttpOnly and that it declares SameSite. If the cookie name suggests a session or authentication (session, auth, token, sid and similar), the finding is medium severity; otherwise low. There is one special case with its own medium severity: SameSite=None without Secure, which modern browsers reject outright, so the cookie does not work and it also reveals a configuration meant for cross-site use. Only the cookies sent in that first response are seen; the ones created after login are better checked with the command below or with the authenticated scan.

What each attribute means

  • Secure: the cookie only travels over HTTPS. Without it, an HTTP request (an old link, a public network) sends it in the clear and anyone on the network reads it.
  • HttpOnly: JavaScript cannot read it. It is the difference between an XSS stealing the session or not being able to.
  • SameSite: when it is sent from another site. Lax sends it on normal navigations but not on requests started by another website; Strict never from outside; None always, and requires Secure. It is the main defence against CSRF.

What an attacker does with a session cookie missing these attributes

Without HttpOnly, any injected script reads document.cookie, sends the value to its server and logs in with your session. Without SameSite, a foreign page can submit a form to your site with the cookie attached and place an order or change an email on the user's behalf. Without Secure, it is enough for the user to open an http:// link to your domain on a shared network. In all three cases the result is the same: someone acts as your user.

How to fix it depending on your framework

// Express with express-session
app.use(session({
  cookie: { secure: true, httpOnly: true, sameSite: 'lax' }
}));

// Next.js (Route Handler or Server Action)
cookies().set('session', value, { httpOnly: true, secure: true, sameSite: 'lax', path: '/' });

// Nuxt (server/api)
setCookie(event, 'session', value, { httpOnly: true, secure: true, sameSite: 'lax', path: '/' });

With Supabase in an app that has a server, the @supabase/ssr library stores the session in cookies with these attributes; in a pure SPA the session goes to localStorage, which is what the token in storage check measures. In Django, Rails or Laravel the attributes are configured in the session settings and come with sensible defaults; check that nobody lowered them to "fix" a development problem.

Check it is fixed

curl -sI https://yourdomain.com | grep -i "set-cookie"
curl -sI -X POST https://yourdomain.com/api/login -d "..." | grep -i "set-cookie"

Every session cookie should show Secure; HttpOnly; SameSite=Lax (or Strict). If your login is a form, look at the response in the browser tools, Network tab, response headers.

Frequently asked questions

My cookie is created by JavaScript (analytics, preferences). It cannot be HttpOnly.

Correct, and that is fine: those cookies give access to nothing. The check flags it at low severity for the missing attribute; what matters is that the session ones do have it.

I need SameSite=None because my app runs inside an iframe on another domain.

Then it is legitimate, always with Secure. Make sure the other CSRF defences (tokens in forms, Origin checks) are active, because SameSite no longer protects you.

Lax or Strict?

Lax for most cases: it keeps the session when the user arrives from an external link. Strict if the cookie gives access to something very sensitive and you accept that the user has to log in again when arriving from outside.

Check it on your site

Scan your site free and see if this and 44 other checks pass, with a fix prompt for every issue.

Scan my site free

From the blog

Related checks