Pular para o conteúdo
Português (BR)

Security headers

Este conteúdo não está disponível em sua língua ainda.

securityHeaders() adds a sensible set of security response headers. Every header is individually overridable, false leaves one out, and a header the handler already set always wins.

It covers its whole subtree, rejections included: a layer below it that short-circuits by throwing HttpError — CSRF, auth, a rate limit — produces a response that carries the headers too.

import { securityHeaders, withMiddleware } from 'actor-ts/http';
const routes = withMiddleware(securityHeaders(), appRoutes);

Defaults: X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Referrer-Policy: no-referrer, Cross-Origin-Opener-Policy: same-origin, Cross-Origin-Resource-Policy: same-origin, and X-XSS-Protection: 0 (the legacy filter is buggy — off is safest). COEP, Permissions-Policy, and HSTS are opt-in.

Builder methodDefault
withContentTypeOptions(flag?)nosniff on
withFrameOptions('DENY' | 'SAMEORIGIN' | false)'DENY'
withReferrerPolicy(value | false)'no-referrer'
withCrossOriginOpenerPolicy(v | false)'same-origin'
withCrossOriginResourcePolicy(v | false)'same-origin'
withCrossOriginEmbedderPolicy(v | false)false (breaks embeds; opt-in)
withPermissionsPolicy(map | false)false
withHsts(options | false)false (opt-in)
const options = SecurityHeadersOptions.create()
.withFrameOptions('SAMEORIGIN')
.withHsts({ maxAge: 31_536_000, preload: true });

CSP is deliberately not part of the bundle — it is too app-specific; configure it with contentSecurityPolicy.

HSTS on its own — strictTransportSecurity

Section titled “HSTS on its own — strictTransportSecurity”
import { strictTransportSecurity, HstsOptions, withMiddleware } from 'actor-ts/http';
const hsts = strictTransportSecurity(
HstsOptions.create().withMaxAge(31_536_000).withIncludeSubDomains().withPreload(),
);

Defaults: max-age 180 days + includeSubDomains. The header is set unconditionally — a browser ignores it over plain HTTP, so a dev server is a harmless no-op, and framework servers usually sit behind a TLS-terminating proxy anyway.

securityHeaders() may wrap a websocket() route like any other — the upgrade completes. What it decorates there is the rejection: a handshake an inner auth middleware refuses comes back carrying these headers. An accepted handshake does not, because the backend writes that 101 response itself. So wrap the whole tree, socket included, rather than carving the socket out. See WebSocket.

  • CSP — Content-Security-Policy.
  • CORS — cross-origin requests.
  • Security — the full recommended stack.