The current NestJS documentation says that starting with NestJS v12.1, app.useSecurityHeaders() sets Helmet 8 style security headers on Express and Fastify with no extra package. On older versions, install Helmet and register it first. Check your installed Nest version before choosing.
Definitions
Security headers tell browsers to switch on protections against known web attacks such as cross site scripting and clickjacking. Examples are Content-Security-Policy, Strict-Transport-Security and X-Frame-Options. Helmet is a middleware package that sets a group of them.
What the built in method does
Per the NestJS docs, the headers are set on every response, including 404 responses, error responses, responses rejected by CSRF protection and Server-Sent Events streams. The X-Powered-By header is removed.
| Header | Documented default |
|---|---|
| Cross-Origin-Opener-Policy | same-origin |
| Cross-Origin-Resource-Policy | same-origin |
| Referrer-Policy | no-referrer |
| Strict-Transport-Security | max-age=31536000; includeSubDomains |
| X-Content-Type-Options | nosniff |
| X-Frame-Options | SAMEORIGIN |
| X-XSS-Protection | 0 |
| X-Powered-By | Removed |
| Cross-Origin-Embedder-Policy | Not sent |
Content-Security-Policy and a few others are also on by default, with the exact policy in the Nest docs.
Rules that trip people up
- Call it before app.init or app.listen. Calling it afterwards, or twice, throws an error.
- Call it right after NestFactory.create. Middleware added with app.use before the call runs first, and responses that middleware sends itself will not carry the headers.
- Options are validated at startup, so a bad configuration fails fast.
- Pass false to omit a header, true for the default, or an object to configure it.
const app = await NestFactory.create(AppModule);
app.useSecurityHeaders();
await app.listen(process.env.PORT ?? 3000);
When Helmet itself still fits
The docs say that to use Helmet itself you install the package for your platform and register it before other app.use calls, because the underlying platform applies middleware in registration order. Helmet remains the choice if you are on a Nest version without the built in method, or need Helmet features such as functions that generate per request nonces. The Nest docs state that function values are not supported by the built in option.
| Situation | Choice |
|---|---|
| Nest version with the built in method, standard policy | useSecurityHeaders |
| Older Nest version | Helmet |
| Per request CSP nonces | Helmet |
Mind the HSTS and CSP defaults
Strict-Transport-Security only matters over HTTPS and browsers ignore it over plain HTTP. A default CSP can break inline scripts and Swagger UI served over plain HTTP, because the upgrade-insecure-requests directive makes browsers load assets over HTTPS. The Nest docs warn that adding unsafe-inline to script-src gives up most of CSP's protection against XSS. Test on staging with real pages before enabling in production.
For the Express side of headers see Helmet and fingerprinting.
Safeguard's DAST web scanning can check a running app's response headers, and a free scan is at gold.safeguard.sh/scan.
Quick check
Does useSecurityHeaders work on both Express and Fastify?
The NestJS docs say it works the same way on both and needs no extra package, starting with v12.1.
Do security headers replace input validation?
No. They are browser side defenses. You still need validation, authorization and output encoding.
Sources
Last reviewed: 19 October 2026.