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