Safeguard
Security Guides•

Express session cookies and login throttling: settings that matter

Cookie options for Express sessions, when cookie-session is the wrong choice, and two counters for limiting login brute force attempts on your login route.

Safeguard Security Team
3 min read

For Express sessions, use a server side store, rename the default cookie, set secure and httpOnly, and configure trust proxy if you sit behind one. For logins, limit failures by username plus IP and by IP alone, using two different time windows.

Pick the right session middleware

The Express docs describe two options. express-session keeps session data on the server and puts only a session ID in the cookie. It defaults to in-memory storage, so the docs tell you to use a scalable session store in production. cookie-session stores the whole session in the cookie, so use it only for small primitive data, keeping the total under 4093 bytes per domain.

If your session holds anything you would not want a user to read or replay, prefer the server side option.

Cookie settings

The docs list these:

  • name: do not keep the default. Set a generic one such as sessionId with the name option, so the cookie does not advertise the framework.
  • secure: send only over HTTPS.
  • httpOnly: block access from client JavaScript.
  • domain and path: restrict where the cookie is sent.
  • expires: set an expiry for persistent cookies.
app.use(session({
  name: 'sessionId',
  secret: process.env.SESSION_SECRET,
  resave: false,
  saveUninitialized: false,
  cookie: { secure: true, httpOnly: true, path: '/', maxAge: 3600000 },
}));

Behind a proxy that terminates TLS, the docs say to set app.set('trust proxy', 1). Without it, a secure cookie may never be set because Express thinks the request is plain HTTP. Only trust the number of proxy hops you actually have.

Brute force protection on login

The Express docs suggest tracking failed attempts two ways:

  1. Consecutive failures for a username and IP address pair.
  2. Total failures from an IP address over a longer period. The example blocks an IP after 100 failures in a day.

The rate-limiter-flexible package implements both. Two counters matter because attackers try many passwords for one account, or one password across many accounts, and a single limit catches only one of those.

A review list

  1. Session secret read from the environment, not source.
  2. Production session store configured, not memory.
  3. Cookie flags set and checked in browser tools.
  4. Proxy hops configured.
  5. Login failures limited two ways, with logging.

Quick check

Why not keep the default cookie name?

The docs recommend a generic name so the cookie does not reveal which middleware you use.

Is rate limiting by IP alone enough?

No. Pair it with a username plus IP counter, as the docs suggest, so slow targeted guessing is also caught.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.