Headers

Secure and HttpOnly Cookie Attributes — What They Do and How to Set Them

Updated April 2026

Reading this? Verify your fix live. Scan your security headers → HeadersFixer

Your session cookie is the most sensitive piece of data in your browser. Two attributes — HttpOnly and Secure — protect it from the two most common attacks. Neither requires any dependencies.

The full secure cookie header

Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=86400

What each attribute does

AttributeProtects againstWhat it does
HttpOnlyXSS cookie theftJavaScript cannot read the cookie via document.cookie
SecureNetwork interceptionCookie only sent over HTTPS, never HTTP
SameSite=LaxCSRF attacksCookie not sent on cross-site POST requests
SameSite=StrictCSRF (stricter)Cookie never sent on any cross-site request
SameSite=None;SecureNothing — use only for cross-site authRequired for OAuth cookies in iframes

Setting secure cookies by framework

Express / Node.js

app.use(session({ secret: process.env.SESSION_SECRET, cookie: { httpOnly: true, // no JS access secure: true, // HTTPS only — set false for localhost dev sameSite: "lax", // CSRF protection maxAge: 86400000,  // 24 hours in milliseconds path: "/", }, resave: false, saveUninitialized: false,
}));

// Or set manually:
res.setHeader("Set-Cookie", "session=abc123; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=86400");

FastAPI / Python

from fastapi import Response

response.set_cookie( key="session", value="abc123", httponly=True, secure=True, samesite="lax", max_age=86400, path="/",
)

Django

# settings.py
SESSION_COOKIE_HTTPONLY = True # default is True — verify it
SESSION_COOKIE_SECURE = True # requires HTTPS
SESSION_COOKIE_SAMESITE = "Lax"  # or "Strict"
SESSION_COOKIE_AGE = 86400

Next.js (cookies() API)

import { cookies } from "next/headers";

cookies().set("session", "abc123", { httpOnly: true, secure: process.env.NODE_ENV === "production", sameSite: "lax", maxAge: 86400, path: "/",
});

Development vs production

# Secure attribute blocks cookies on HTTP (localhost)
# Use a flag:

const isProd = process.env.NODE_ENV === "production";

cookie: { secure: isProd,  // false on localhost, true in production httpOnly: true,  // always on sameSite: "lax", // always on
}

Check your cookies in DevTools

DevTools → Application → Cookies → your domain. You should see checkmarks for HttpOnly and Secure columns on session cookies. If the HttpOnly column is empty — that cookie is readable by JavaScript.

Scan your security headers → HeadersFixer
Check if your domain is on the HSTS preload list → HSTS Preload Checker