Complete Guide to HTTP Security Headers in 2026: CSP, HSTS, X-Frame-Options & Permissions Policy
Deep dive into configuring modern HTTP response headers in Next.js and Nginx. Defend against cross-site scripting (XSS), clickjacking, and MIME sniffing.

1. The Crucial Role of Defense-in-Depth Headers
Application-layer security starts in the code, but browser enforcement begins with HTTP response headers. Security headers instruct user agents to constrain execution permissions, restrict asset origins, and reject unencrypted transports before JavaScript is executed.
Web security audits and penetration tests frequently flag missing or misconfigured headers as moderate-to-high risk vulnerabilities.
2. Content-Security-Policy (CSP) Demystified
Content-Security-Policy is the single most effective defense against Cross-Site Scripting (XSS) and unauthorized resource injection. By specifying whitelisted origins for scripts, styles, images, and fonts, you disallow malicious scripts injected into DOM nodes from fetching payloads or executing.
A modern, strict CSP disallows `unsafe-inline` scripts by using cryptographic nonces or sha256 hashes generated dynamically per request.
import { NextResponse } from "next/server";
import type { NextRequest } from "next/request";
export function middleware(request: NextRequest) {
const nonce = Buffer.from(crypto.randomUUID()).toString("base64");
const response = NextResponse.next();
const cspHeader = `
default-src 'self';
script-src 'self' 'nonce-${nonce}' 'strict-dynamic';
style-src 'self' 'unsafe-inline';
img-src 'self' blob: data: https:;
font-src 'self' data:;
object-src 'none';
base-uri 'self';
form-action 'self';
frame-ancestors 'none';
upgrade-insecure-requests;
`.replace(/\s{2,}/g, " ").trim();
response.headers.set("Content-Security-Policy", cspHeader);
response.headers.set("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload");
response.headers.set("X-Frame-Options", "DENY");
response.headers.set("X-Content-Type-Options", "nosniff");
response.headers.set("Referrer-Policy", "strict-origin-when-cross-origin");
response.headers.set("Permissions-Policy", "camera=(), microphone=(), geolocation=()");
return response;
}3. Enforcing HSTS and Preload Eligibility
HTTP Strict Transport Security (HSTS) informs browsers that a site must only be reached using HTTPS. Without HSTS, a user typing `example.com` makes an initial plaintext HTTP request that attackers can intercept with SSL stripping tools.
Specifying `includeSubDomains` protects wildcard internal hostnames, and adding `preload` allows inclusion in the global Chromium/Firefox HSTS preload list hardcoded into browser binaries.
4. Validating Your Live Configuration
Deploying headers without real-world validation can break external embeds, web fonts, or analytics endpoints. Use an automated scanner such as our Website Health Checker to verify status codes, TLS certificates, and header compliance before rolling out to production traffic.