Skip to content

Security Headers (Helmet) ​

The helmet() middleware sets security-related HTTP headers with sensible defaults for API servers. Zero external dependencies.

Usage ​

ts
import { helmet } from '@forinda/kickjs'

bootstrap({
  middlewares: [helmet(), requestId(), express.json()],
})

Default Headers ​

HeaderDefault ValuePurpose
X-Content-Type-OptionsnosniffPrevents MIME type sniffing
X-Frame-OptionsDENYPrevents clickjacking
X-XSS-Protection0Disables legacy XSS auditor (causes more harm than good)
Referrer-Policyno-referrerControls referrer information
X-DNS-Prefetch-ControloffDisables DNS prefetching
Strict-Transport-Securitymax-age=31536000; includeSubDomainsEnforces HTTPS
X-Powered-By(removed)Hides server technology

Options ​

ts
helmet({
  // Disable individual headers
  frameguard: false,
  hsts: false,
  referrerPolicy: false,

  // Change values
  frameguard: 'SAMEORIGIN',
  referrerPolicy: 'strict-origin-when-cross-origin',

  // HSTS with preload
  hsts: { maxAge: 63072000, includeSubDomains: true, preload: true },

  // Content Security Policy
  contentSecurityPolicy: {
    'default-src': ["'self'"],
    'script-src': ["'self'", 'https://cdn.example.com'],
    'style-src': ["'self'", "'unsafe-inline'"],
  },
})

Sub-path Import ​

ts
import { helmet } from '@forinda/kickjs/middleware/helmet'

CORS ​

The cors() middleware handles Cross-Origin Resource Sharing with correct spec behavior.

Usage ​

ts
import { cors } from '@forinda/kickjs'

// Allow all origins (default)
bootstrap({
  middlewares: [cors(), helmet(), express.json()],
})

// Allowlist specific origins
bootstrap({
  middlewares: [
    cors({
      origin: ['https://app.example.com', /\.example\.com$/],
      credentials: true,
    }),
    helmet(),
    express.json(),
  ],
})

Options ​

ts
interface CorsOptions {
  origin?: boolean | string | RegExp | (string | RegExp)[]
  methods?: string[] // default: GET, HEAD, PUT, PATCH, POST, DELETE
  allowedHeaders?: string[] // default: reflects request headers
  exposedHeaders?: string[] // default: none
  credentials?: boolean // default: false
  maxAge?: number // default: 86400 (24h)
  preflight?: boolean // default: true
}

Origin Matching ​

ValueBehavior
'*'Allow all origins (default)
trueReflect the request's Origin header
'https://app.example.com'Exact match
/\.example\.com$/Regex match
['https://a.com', /\.b\.com$/]Array of string/regex

When reflecting origins (not '*'), the middleware sets Vary: Origin for correct CDN/proxy caching.

Credentials ​

When credentials: true, the browser sends cookies and authorization headers cross-origin. This requires a specific origin (not '*'):

ts
cors({
  origin: ['https://app.example.com'],
  credentials: true,
})

Preflight ​

OPTIONS requests are handled with 204 No Content, Access-Control-Allow-Methods, Access-Control-Allow-Headers, and Access-Control-Max-Age.

Sub-path Import ​

ts
import { cors } from '@forinda/kickjs/middleware/cors'

Allowed Hosts ​

Host is chosen by the client. Code that builds absolute URLs from it — password-reset and verification links, redirects, Location headers — hands an attacker a link to their own domain, and a shared cache can store a response built for the wrong host. Name the hosts your app serves, and every other request answers 400 problem details:

ts
bootstrap({
  modules,
  security: { allowedHosts: ['example.com', '.example.com'] },
})
PatternMatches
'example.com'exactly example.com
'.example.com'example.com and every subdomain
'*'anything — turns the check off

Ports are ignored, and names compare case-insensitively.

  • Health probes are exempt. Kubernetes and most platforms probe the instance's IP, so GET/HEAD on /health/live and /health/ready answer whatever the host. The check runs before anything else is mounted, including routes adapters register.

  • Behind a proxy that rewrites Host, read the original from X-Forwarded-Host — only when your proxy sets it, since clients can send it too. Every value in the header must be allowed, since frameworks disagree about which one to read. Without this option the header is removed from the request, so nothing reads a host the check didn't see:

    ts
    security: { allowedHosts: { hosts: ['example.com'], trustForwardedHost: true } }
  • As middleware, allowedHosts() takes the same options plus ignorePaths (exempt for GET and HEAD only), for apps that mount their own chain:

    ts
    import { allowedHosts } from '@forinda/kickjs'
    
    bootstrap({ middlewares: [allowedHosts(['example.com']) /* , … */] })

Released under the MIT License. Built with TypeScript — runs on Express, Fastify, or h3.