Security Headers

Security Headers provides a unified configuration for protecting your Express applications from common web vulnerabilities like Cross-Site Scripting (XSS), Clickjacking, and Cross-Origin Resource Sharing (CORS) issues.

It leverages industry-standard tools:

  • Helmet: A collection of 15 smaller middleware functions that set security-related HTTP headers.
  • CORS: Middleware to enable Cross-Origin Resource Sharing with various options.

Installation Guide

Install the component using the Servercn CLI:

npx servercn-cli add security-header

Threat Model Coverage

Below is a precise breakdown of each header, the associated attack vector, and the mitigation strategy.

Attack

Browsers attempt MIME sniffing and may execute JavaScript disguised as another file type (e.g., malicious JS embedded in an image upload).

Mitigation

Forces browsers to strictly honor the declared Content-Type header.


Attack (Clickjacking)

An attacker embeds your application inside a malicious iframe and overlays invisible UI elements to trick users into clicking privileged actions.

Mitigation

Prevents your application from being framed.


History & Risk

Legacy browsers implemented a reflective XSS filter that was unreliable and, in some cases, exploitable.

Modern Best Practice

Disable it (0) and rely on a properly configured Content-Security-Policy (CSP).


Attack (Protocol Downgrade / MITM)

An attacker forces HTTPS traffic to downgrade to HTTP.

Mitigation

Instructs the browser to only use HTTPS for your domain for a defined duration.


Attack (XSS Injection)

An attacker injects malicious <script> tags into your pages.

Mitigation

Whitelists allowed script, style, image, and connection sources.


Data Leakage Risk

The Referer header may expose full URLs including tokens, internal paths, or identifiers when navigating away.

Mitigation

Controls how much URL information is shared with external origins.


Attack Surface Expansion

Malicious embedded contexts (iframes) attempt to access camera, microphone, geolocation, etc.

Mitigation

Explicitly disables browser capabilities your application does not require.


Information Disclosure

X-Powered-By: Express reveals your framework stack.

Mitigation

Disable to reduce reconnaissance surface area.


What This Component Solves

Manually configuring security headers can be error-prone and tedious. This component standardizes:

  • XSS Protection: Prevents browsers from loading scripts that appear to be XSS attacks.
  • Clickjacking Protection: Prevents your site from being embedded in an iframe.
  • Content Type Sniffing: Prevents browsers from trying to guess the content type.
  • CORS Policy: Configures which domains can access your API.

Implementation

The component provides a configureSecurityHeaders function that you should call during your Express app initialization.

MVC: src/middlewares/security-header.ts

Feature: src/shared/middlewares/security-header.ts

Minimal

import cors from "cors";
import { Express } from "express";
import helmet from "helmet";
 
export const configureSecurityHeaders = (app: Express) => {
  app.use(helmet());
 
  app.use(
    cors({
      origin: process.env.CORS_ORIGIN || "*",
      credentials: true,
      methods: ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"],
      allowedHeaders: ["Content-Type", "Authorization", "X-Requested-With"]
    })
  );
 
  app.use((req, res, next) => {
    res.setHeader("X-Content-Type-Options", "nosniff");
    res.setHeader("X-Frame-Options", "DENY");
    res.setHeader("X-XSS-Protection", "1; mode=block");
    next();
  });
};

Advanced

import cors from "cors";
import { Express } from "express";
import helmet from "helmet";
 
export const configureSecurityHeaders = (app: Express) => {
  // Remove framework fingerprint
  app.disable("x-powered-by");
 
  // Helmet with explicit security policy configuration
  app.use(
    helmet({
      xssFilter: false, // disable legacy X-XSS-Protection
      contentSecurityPolicy: {
        directives: {
          defaultSrc: ["'self'"],
          scriptSrc: ["'self'"],
          styleSrc: ["'self'"],
          imgSrc: ["'self'", "data:"],
          connectSrc: ["'self'"],
          objectSrc: ["'none'"],
          frameAncestors: ["'none'"],
          upgradeInsecureRequests: []
        }
      },
      hsts: {
        maxAge: 63072000, // 2 years
        includeSubDomains: true,
        preload: true
      },
      referrerPolicy: {
        policy: "strict-origin-when-cross-origin"
      },
      permissionsPolicy: {
        features: {
          camera: [],
          microphone: [],
          geolocation: [],
          payment: []
        }
      }
    })
  );
 
  // CORS configuration
  app.use(
    cors({
      origin: process.env.CORS_ORIGIN || "*",
      credentials: true,
      methods: ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"],
      allowedHeaders: ["Content-Type", "Authorization", "X-Requested-With"]
    })
  );
 
  // Explicit header hardening overrides
  app.use((req, res, next) => {
    res.setHeader("X-Content-Type-Options", "nosniff");
    res.setHeader("X-Frame-Options", "DENY");
    res.setHeader("X-XSS-Protection", "0"); // modern best practice
    next();
  });
};

Import and use the configuration in your main app.ts file.

import express from "express";
import { configureSecurityHeaders } from "./middlewares/security-header";
 
const app = express();
 
// Apply security headers before other middlewares and routes
configureSecurityHeaders(app);
 
app.use(express.json());
// ... rest of your app

Production Recommendations

Never use * in production for authenticated APIs.

cors({
  origin: "https://your-frontend-domain.com"
  // ...
});

If using CDNs or third-party services:

app.use(
  helmet({
    contentSecurityPolicy: {
      directives: {
        defaultSrc: ["'self'"],
        scriptSrc: ["'self'", "trusted-scripts.com"],
        imgSrc: ["'self'", "res.cloudinary.com"]
      }
    }
  })
);

Once deployed over HTTPS permanently, consider submitting to the HSTS preload list.

Verification

You can verify your security headers using online tools like SecurityHeaders.com.

Security Outcome

  • With this configuration, your Servercn Express application gains:
  • Hardened XSS defense
  • Clickjacking prevention
  • HTTPS enforcement
  • Reduced fingerprinting
  • Controlled cross-origin access
  • Minimized browser feature abuse
  • Referrer data protection

File & Folder Structure

ServerCN

Select a file to view its contents

Installation

npx servercn-cli add security-header