Safeguard
Developer Tools•

NestJS security headers: use app.useSecurityHeaders or Helmet?

Newer NestJS docs describe app.useSecurityHeaders with Helmet 8 defaults on Express and Fastify. See the headers, call order rules and when Helmet fits.

Safeguard Security Team
3 min read

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.

HeaderDocumented default
Cross-Origin-Opener-Policysame-origin
Cross-Origin-Resource-Policysame-origin
Referrer-Policyno-referrer
Strict-Transport-Securitymax-age=31536000; includeSubDomains
X-Content-Type-Optionsnosniff
X-Frame-OptionsSAMEORIGIN
X-XSS-Protection0
X-Powered-ByRemoved
Cross-Origin-Embedder-PolicyNot 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

  1. Call it before app.init or app.listen. Calling it afterwards, or twice, throws an error.
  2. 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.
  3. Options are validated at startup, so a bad configuration fails fast.
  4. 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.

SituationChoice
Nest version with the built in method, standard policyuseSecurityHeaders
Older Nest versionHelmet
Per request CSP noncesHelmet

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.

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.