Server & Application Hardening

6 Essential HTTP Security Headers Every Website Needs in 2026

Protect your website without code changes. Complete guide to the 6 essential HTTP security headers with production-ready Nginx, Apache, and Caddy snippets.

By AuditYourWeb9 min read
Security shield illustrating HTTP response header protection

Why HTTP security headers matter

Modern web browsers come equipped with powerful defensive mechanisms designed to protect visitors against Cross-Site Scripting (XSS), clickjacking, MIME-type sniffing, and man-in-the-middle packet injection.

However, browsers operate in standard compatibility mode by default. They will not activate these protective barriers unless your web server explicitly instructs them to do so via HTTP response headers.

Adding security headers requires no changes to your application code or database. A few simple lines in your Nginx, Apache, Caddy, or Next.js configuration can eliminate entire categories of critical OWASP vulnerabilities.


The 6 essential security headers

1. Strict-Transport-Security (HSTS)

HSTS guarantees that client browsers connect to your website exclusively over encrypted HTTPS, completely ignoring accidental http:// links.

  • Recommended Value: max-age=31536000; includeSubDomains; preload
  • What it does: Enforces a 1-year (31,536,000 seconds) TLS upgrade, protects all subdomains, and qualifies your domain for the global browser HSTS preload list.

2. Content-Security-Policy (CSP)

Widely recognized as the ultimate client-side defense against Cross-Site Scripting (XSS), CSP restricts the exact origins from which scripts, styles, fonts, and images can execute.

  • Recommended Baseline: default-src 'self'; script-src 'self'; object-src 'none'; img-src 'self' data: https:;
  • What it does: Prevents malicious injected <script> tags from executing and sending stolen cookies or auth tokens to rogue endpoints.

3. X-Frame-Options

Protects your visitors against clickjacking (UI redress attacks) by forbidding third-party sites from embedding your web pages inside invisible <iframe> overlays.

  • Recommended Value: SAMEORIGIN (or DENY)
  • What it does: Disallows external domains from embedding your login forms, checkout pages, or settings panels inside iframes.

4. X-Content-Type-Options

Prevents browsers from MIME-sniffing a response away from the declared Content-Type.

  • Recommended Value: nosniff
  • What it does: Forces browsers to strictly respect declared file types. If a user uploads an image containing malicious JavaScript, nosniff prevents the browser from executing that image as script code.

5. Referrer-Policy

Controls what private information (pathnames, user IDs, authentication tokens in URLs) is broadcast in the Referer header when visitors click outbound links.

  • Recommended Value: strict-origin-when-cross-origin
  • What it does: Sends full path data only to the same origin; for cross-origin HTTPS visits, it only transmits your domain name (e.g., https://yourdomain.com/), protecting private query parameters.

6. Permissions-Policy (Formerly Feature-Policy)

Grants granular control over modern browser hardware APIs, disabling sensitive device capabilities unless explicitly authorized.

  • Recommended Value: camera=(), microphone=(), geolocation=()
  • What it does: Blocks third-party scripts or embedded ads from secretly accessing user webcam hardware, audio microphones, or geolocation coordinates.

Nginx configuration snippet

To enable all six security headers across your entire Nginx web server, add the following directives inside your server { ... } block (typically located in /etc/nginx/sites-available/ or /etc/nginx/conf.d/):

# /etc/nginx/conf.d/security-headers.conf
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; object-src 'none';" always;

# Hide server version details from attackers
server_tokens off;

Test your configuration syntax and reload Nginx:

sudo nginx -t && sudo systemctl reload nginx

Apache (.htaccess) configuration snippet

If you run an Apache web server, ensure mod_headers is enabled (sudo a2enmod headers) and place the following block in your root .htaccess or virtual host configuration:

# .htaccess Security Headers
<IfModule mod_headers.c>
  Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
  Header always set X-Content-Type-Options "nosniff"
  Header always set X-Frame-Options "SAMEORIGIN"
  Header always set Referrer-Policy "strict-origin-when-cross-origin"
  Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
  Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; object-src 'none';"
</IfModule>

# Suppress Apache signature & version leaks
ServerSignature Off
ServerTokens Prod

Caddy and Next.js configuration

Caddy Server (Caddyfile)

Caddy automatically handles HTTPS, but adding custom headers is clean and concise:

yourdomain.com {
    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
        X-Content-Type-Options "nosniff"
        X-Frame-Options "SAMEORIGIN"
        Referrer-Policy "strict-origin-when-cross-origin"
        Permissions-Policy "camera=(), microphone=(), geolocation=()"
        Content-Security-Policy "default-src 'self'; script-src 'self'; object-src 'none';"
        -Server
    }
    reverse_proxy localhost:3000
}

Next.js (next.config.js)

In Next.js applications, configure headers directly in next.config.js:

// next.config.js
module.exports = {
  poweredByHeader: false, // Disables X-Powered-By: Next.js
  async headers() {
    return [
      {
        source: '/(.*)',
        headers: [
          { key: 'Strict-Transport-Security', value: 'max-age=31536000; includeSubDomains; preload' },
          { key: 'X-Content-Type-Options', value: 'nosniff' },
          { key: 'X-Frame-Options', value: 'SAMEORIGIN' },
          { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
          { key: 'Permissions-Policy', value: 'camera=(), microphone=(), geolocation=()' },
          { key: 'Content-Security-Policy', value: "default-src 'self'; script-src 'self' 'unsafe-inline'; object-src 'none';" },
        ],
      },
    ];
  },
};

How to test your security headers grade

After applying your server changes, verify your headers using our free HTTP Security Headers Validator.

The validator analyzes your live response headers, flags missing defenses or information leaks (like Server or X-Powered-By version broadcasting), and assigns a letter grade from A+ to F.

You can also inspect response headers directly via terminal curl:

curl -I "https://yourdomain.com"

Got questions?

Frequently Asked Questions

Quick answers to common questions about 6 essential http security headers every website needs in 2026.

If you use Google Tag Manager, Google Analytics, or Google Fonts, an overly strict CSP that allows only 'self' will block those external scripts. You must whitelist the trusted domains in your directives (e.g. script-src 'self' https://www.googletagmanager.com; font-src 'self' https://fonts.gstatic.com;).

Continue reading

How DNS Propagation Works (And Why It Takes Up to 48 Hours)

Why do DNS changes take hours to go live? Learn how TTL caching works across global ISP resolvers, how to avoid caching traps, and how to verify propagation.

Read the guide
Back to all guides
6 Essential HTTP Security Headers (With Nginx & Apache Snippets)