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
| Attribute | Protects against | What it does |
|---|---|---|
| HttpOnly | XSS cookie theft | JavaScript cannot read the cookie via document.cookie |
| Secure | Network interception | Cookie only sent over HTTPS, never HTTP |
| SameSite=Lax | CSRF attacks | Cookie not sent on cross-site POST requests |
| SameSite=Strict | CSRF (stricter) | Cookie never sent on any cross-site request |
| SameSite=None;Secure | Nothing — use only for cross-site auth | Required 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