Guides

HTTP Security Headers: The Complete Guide for 2025

Practical guide to configuring HSTS, CSP, X-Frame-Options and other critical HTTP security headers for your web application.

5 March 20254 min readWarDek Team

HTTP security headers are often overlooked, but they provide a simple and effective defense against many common attacks. Correctly configuring 6 headers eliminates entire classes of vulnerabilities.

Why Security Headers Are Critical

A misconfigured (or missing) header can allow:

WarDek automatically analyzes these 12 headers during every scan.

The 6 Essential Headers

1. Strict-Transport-Security (HSTS)

Forces browsers to use HTTPS for all future connections, even if the user types http://.

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

Parameters:

Warning: Once enabled with preload, it's difficult to undo. Test first with a shorter max-age.

2. Content-Security-Policy (CSP)

The most powerful header — and the most complex. Defines allowed sources for each resource type.

Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-{random}'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; frame-ancestors 'none'

Basic rules:

3. X-Frame-Options

Protects against clickjacking by controlling who can embed your page in an iframe.

X-Frame-Options: DENY

Or to allow only your own domain:

X-Frame-Options: SAMEORIGIN

Note: frame-ancestors in CSP is more flexible and supersedes X-Frame-Options in modern browsers. Keep both for compatibility.

4. X-Content-Type-Options

Prevents the browser from guessing a resource's MIME type (MIME sniffing), which can lead to malicious code execution.

X-Content-Type-Options: nosniff

Simple, one possible value. Enable it consistently.

5. Referrer-Policy

Controls information sent in the Referer header when navigating between pages.

Referrer-Policy: strict-origin-when-cross-origin

This limits the leakage of internal URLs (which might contain tokens or sensitive data) during cross-origin requests.

6. Permissions-Policy (formerly Feature-Policy)

Controls access to browser APIs (camera, microphone, geolocation, etc.).

Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=()

If your application doesn't use these APIs, disable them to reduce the attack surface.

Headers to Remove

Equally important: remove headers that reveal information about your infrastructure.

These headers facilitate automated reconnaissance. An attacker who identifies your Apache or PHP version can immediately look up corresponding CVEs in public vulnerability databases.

Implementation by Stack

Nginx

server {
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    add_header Content-Security-Policy "default-src 'self'; script-src 'self'" always;
    add_header X-Frame-Options "DENY" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;

    # Remove informational headers
    server_tokens off;
    proxy_hide_header X-Powered-By;
}

Apache

Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Header always set X-Frame-Options "DENY"
Header always set X-Content-Type-Options "nosniff"
Header always set Referrer-Policy "strict-origin-when-cross-origin"

# Hide version info
ServerTokens Prod
ServerSignature Off

Next.js / Vercel

// next.config.ts
const securityHeaders = [
  { key: 'Strict-Transport-Security', value: 'max-age=31536000; includeSubDomains; preload' },
  { key: 'X-Frame-Options', value: 'DENY' },
  { key: 'X-Content-Type-Options', value: 'nosniff' },
  { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
];

Common Mistakes

Overly permissive CSP. A Content-Security-Policy: default-src * protects against nothing. Start restrictive ('self') and add exceptions one at a time.

HSTS without prior testing. Enabling preload on a domain that is not fully HTTPS can make your site inaccessible. Test with a short max-age (300 seconds) first.

Forgetting subdomains. Without includeSubDomains in HSTS, an attacker can exploit an unsecured subdomain to intercept cookies from the main domain.

Contradictory CSP and X-Frame-Options. If your CSP says frame-ancestors 'self' but X-Frame-Options says DENY, behavior depends on the browser. Align both headers.

How to Check Your Configuration

  1. WarDek: Automatic scan of all your headers with scores and recommendations
  2. securityheaders.com: Free tool for a quick check
  3. curl: curl -I https://yoursite.com to see raw headers
  4. Browser DevTools: Network tab, select the main request, inspect Response Headers

A good security headers score also improves your SEO ranking (Google favors well-configured HTTPS sites) and your NIS2 compliance. The NIS2 directive (Article 21) explicitly requires network security measures, of which HTTP headers are an integral part.

Frequently Asked Questions

Do I need all 6 headers on every page? Yes. Security headers should be set globally at the server or reverse proxy level, not per-route. Missing a header on a single endpoint creates a vulnerability window that attackers actively scan for.

Will strict CSP break my website? It can, which is why you should deploy in report-only mode first. Use Content-Security-Policy-Report-Only with a reporting endpoint to collect violations for at least one week before switching to enforcement mode.

How do security headers interact with CDNs? Most CDNs (Cloudflare, AWS CloudFront, Fastly) let you add or override response headers at the edge. Configure your security headers at the CDN level to ensure they are applied consistently, even if your origin server configuration varies across deployments.

#headers#web-security#configuration#best-practices

Scan your site for free

WarDek detects the vulnerabilities mentioned in this article in seconds.

Back to Guides