Skip to content

Express

Facts last verified 2026-07-26 against Express 5.2.1

Express is the inverse of Django. Django ships most protections on and the work is finding what got turned off; Express ships almost nothing, so nearly every control here is something you add — usually from a package, usually once, usually without reading what it did.

That difference shapes this cluster. Most of these pages are less about a setting being wrong than about a dependency behaving differently from the guide that told you to install it.

Terminal window
node -e "console.log(require('express/package.json').version)"
npm ls helmet express-session cors express-rate-limit csurf

Express 5.2.1 is current. Two things worth knowing if you are still on 4.x: body parsing has been built in since 4.16, so npm install body-parser has been unnecessary for years, and Express 5 changed the default query parser to 'simple' (read from lib/application.js), which no longer builds nested objects out of query strings.

If that npm ls prints csurf, start there — it has been archived since 2020 and still installs without complaint. See csurf is archived.

trust proxy decides whether req.ip is something you observed or something the client claimed. Secure cookies, rate limiting and every IP-based rule inherit it, and both of its obvious values are wrong for a proxied deployment — unset breaks secure cookies, true makes req.ip forgeable.

It is worth reading trust proxy before the pages that depend on it, and it is why this cluster’s threat page is about a configuration value rather than a CVE.

Severity is the exposure a control closes, not how often it gets recommended. Two entries are rated low and say so on the page — including X-Powered-By, where the package that removes the header describes the benefit as “very limited”.

Session secret and storeForgeable sessions, and a store that leaks memory under loadSeverity: critical
Stack traces in error responsesSource paths, dependency versions and internal structure disclosed on any unhandled errorSeverity: high
Session cookie flagsSession cookie sent over plaintext, or readable by injected scriptSeverity: high
trust proxySpoofed client IPs, or secure cookies that never reach the browserSeverity: high
CORS configurationAny website reading authenticated responses from your API in a visitor's browserSeverity: high
csurf is archived — CSRF protection in ExpressState-changing requests forged from another site using the visitor's cookiesSeverity: high
What helmet actually setsMissing response headers, or a default CSP shipped without testingSeverity: medium
Rate limitingCredential stuffing and brute force against login and reset endpointsSeverity: medium
Request body size limitsMemory exhaustion from oversized request bodiesSeverity: low
X-Powered-ByFramework disclosure — obscurity onlySeverity: low
Client IP spoofing via trust proxyEvery IP-based control in the application defeated by one headerSeverity: high
0 of 11 applied

Node itself, the process manager, TLS termination, and the proxy in front of you. That is the server’s half rather than the application’s — see application vs server for the dividing line, and for the three controls that genuinely span both.