DEV Community

Hieu Le
Hieu Le

Posted on Originally published at sitecheckly.com

Security Headers List: 6 Headers Every Site Needs in 2026

Originally published on Sitecheckly.

A robust security headers list includes Content-Security-Policy, Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, and Permissions-Policy. These HTTP response headers protect against cross-site scripting (XSS), clickjacking, MIME sniffing, and unwanted data leaks. Implementing them requires adding simple response directives in your web server or hosting configuration.

Why are security headers critical for website protection?

HTTP security headers instruct web browsers to enforce security restrictions. They act as a defense layer directly inside the client browser, reducing your attack surface without requiring alterations to your application code.

When HTTP response headers are missing, browsers default to permissive behaviors. This exposes your users to common web vulnerabilities such as clickjacking, session hijacking, and cross-site scripting (XSS). According to guidelines from the OWASP Secure Headers Project, deploying server-level response directives is one of the most effective ways to secure web applications.

Despite their importance, missing security headers remain widespread across the web. 84% of the 97 sites audited on Sitecheckly in the last 90 days had this issue: "Missing security headers". Adding these headers takes only a few minutes and significantly hardens your infrastructure.

What are the 6 security headers every website should send?

Here are the six essential HTTP security headers recommended for production websites.

Header Name Recommended Value Primary Function
Strict-Transport-Security max-age=31536000; includeSubDomains Forces HTTPS connections
Content-Security-Policy default-src 'self'; script-src 'self'; object-src 'none'; Restricts resource loading to block XSS
X-Frame-Options DENY Blocks iframe embedding to prevent clickjacking
X-Content-Type-Options nosniff Stops MIME type sniffing
Referrer-Policy strict-origin-when-cross-origin Controls referrer data sent in request headers
Permissions-Policy camera=(), microphone=(), geolocation=() Disables unwanted browser features

1. Strict-Transport-Security (HSTS)

HSTS forces browsers to interact with your website exclusively over encrypted HTTPS connections. It protects users against protocol downgrade attacks and cookie hijacking.

3 of the 5 sites audited on Sitecheckly in the last 90 days had this issue: "Missing HSTS (Strict-Transport-Security)" (small sample). You can learn more about directives such as max-age, includeSubDomains, and preload in the MDN HSTS documentation.

Warning: Adding the preload directive submits your domain to browser-hardcoded HSTS preload lists. HSTS preloading is difficult and slow to undo if you misconfigure HTTPS or need to drop back to HTTP. Do not include preload until you have tested your HTTPS setup thoroughly and confirmed all subdomains support HTTPS.

2. Content-Security-Policy (CSP)

Content-Security-Policy controls which dynamic resources (scripts, stylesheets, images) the browser is allowed to load. By restricting resource origins, CSP blocks unauthorized inline scripts and mitigates XSS attacks.

5 of the 5 sites audited on Sitecheckly in the last 90 days had this issue: "Missing Content-Security-Policy (CSP)" (small sample). Review the MDN CSP documentation for syntax and implementation details.

Note on 'unsafe-inline': Including 'unsafe-inline' in your style-src or script-src directives disables XSS protection for inline elements. Attackers can inject malicious inline styles or scripts if this keyword is present. Use nonces, hashes, or external stylesheets instead of 'unsafe-inline' whenever possible.

3. X-Frame-Options

X-Frame-Options controls whether your website can be embedded in <frame>, <iframe>, <embed>, or <object> elements. Setting this header to DENY or SAMEORIGIN prevents clickjacking attacks, where malicious sites overlay invisible frames over your interface.

4. X-Content-Type-Options

Browsers sometimes attempt to guess (sniff) the MIME type of a file if the server does not state it correctly. An attacker could upload a text file containing malicious script tags and trick the browser into executing it. Setting X-Content-Type-Options: nosniff forces the browser to adhere strictly to the declared Content-Type header.

5. Referrer-Policy

The Referrer-Policy header determines how much URL information is sent in the Referer request header when users navigate away from your page. Using strict-origin-when-cross-origin sends full URL paths for same-origin requests, but sends only the domain origin for cross-origin HTTPS requests, preventing sensitive query parameters from leaking to third parties.

6. Permissions-Policy

Permissions-Policy allows site owners to restrict access to browser features and APIs. Disabling unused hardware features like the camera, microphone, and geolocation API reduces potential abuse if your application is compromised.

How do you configure security headers in Nginx?

To set security headers in Nginx, use the add_header directive inside your server or location block. Always append the always parameter to ensure headers are sent regardless of the response status code (including 4xx and 5xx errors).

Note: Nginx directives defined at an upper block level are overridden if a child block defines its own add_header directive. Ensure all required headers are present in child blocks if defined locally.

Warning: The CSP directive below includes 'unsafe-inline' in style-src as a temporary compatibility fallback for legacy inline styles. Using 'unsafe-inline' exposes your site to style injection attacks. Remove 'unsafe-inline' once inline styles are moved to external files or secured with nonces.

server {
    listen 443 ssl http2;
    server_name example.com;

    # Security Headers
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; object-src 'none';" 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;
}
Enter fullscreen mode Exit fullscreen mode

How do you configure security headers in Apache?

In Apache, use mod_headers to apply security headers across your application. You can place these directives in your main httpd.conf server configuration file or within an .htaccess file in your document root directory.

Always use Header always set instead of Header set to ensure headers are included in error responses as well as success responses.

Warning: The CSP directive below includes 'unsafe-inline' in style-src as a temporary compatibility fallback for legacy inline styles. Using 'unsafe-inline' exposes your site to style injection attacks. Remove 'unsafe-inline' once inline styles are moved to external files or secured with nonces.

<IfModule mod_headers.c>
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
    Header always set Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; object-src 'none';"
    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"
    Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
</IfModule>
Enter fullscreen mode Exit fullscreen mode

How do you set response headers in Cloudflare, Next.js, and Vercel?

Deployments using modern hosting platforms or edge networks offer dedicated configuration mechanisms for HTTP headers.

Cloudflare

You can add response headers at the edge using Cloudflare HTTP Response Header Transform Rules:

  1. Log in to your Cloudflare Dashboard and select your domain.
  2. Navigate to Rules > Transform Rules.
  3. Select the Modify Response Header tab.
  4. Click Create rule, name your rule, and set matching criteria to All incoming requests.
  5. Choose Set dynamic or Set static for each header name (e.g., Strict-Transport-Security) and enter your target value.
  6. Click Deploy.

Next.js

In Next.js applications, define HTTP response headers in next.config.js using the headers() async function. Refer to the Next.js headers documentation for full syntax details.

Note: The style-src directive below contains 'unsafe-inline', which reduces CSP security by allowing inline CSS execution. Remove this keyword when your application no longer relies on inline styles.

/** @type {import('next').NextConfig} */
const nextConfig = {
  async headers() {
    return [
      {
        source: '/:path*',
        headers: [
          {
            key: 'Strict-Transport-Security',
            value: 'max-age=31536000; includeSubDomains',
          },
          {
            key: 'Content-Security-Policy',
            value: "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; object-src 'none';",
          },
          {
            key: 'X-Frame-Options',
            value: 'DENY',
          },
          {
            key: 'X-Content-Type-Options',
            value: 'nosniff',
          },
          {
            key: 'Referrer-Policy',
            value: 'strict-origin-when-cross-origin',
          },
          {
            key: 'Permissions-Policy',
            value: 'camera=(), microphone=(), geolocation=()',
          },
        ],
      },
    ];
  },
};

module.exports = nextConfig;
Enter fullscreen mode Exit fullscreen mode

Vercel

If you deploy static assets or custom backends to Vercel without Next.js, configure headers using a vercel.json file in your root directory:

Note: The style-src directive below contains 'unsafe-inline', which reduces CSP security by allowing inline CSS execution. Remove this keyword when your application no longer relies on inline styles.

{
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        {
          "key": "Strict-Transport-Security",
          "value": "max-age=31536000; includeSubDomains"
        },
        {
          "key": "Content-Security-Policy",
          "value": "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; object-src 'none';"
        },
        {
          "key": "X-Frame-Options",
          "value": "DENY"
        },
        {
          "key": "X-Content-Type-Options",
          "value": "nosniff"
        },
        {
          "key": "Referrer-Policy",
          "value": "strict-origin-when-cross-origin"
        },
        {
          "key": "Permissions-Policy",
          "value": "camera=(), microphone=(), geolocation=()"
        }
      ]
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

How to test and verify your HTTP security headers?

After deploying your configuration, verify that your web server outputs the correct response headers.

Command Line Verification

Use curl to inspect response headers for your domain:

curl -I https://example.com
Enter fullscreen mode Exit fullscreen mode

Check the command output to verify that all six headers appear with their expected values.

Browser Developer Tools

  1. Open Google Chrome, Firefox, or Safari.
  2. Open Developer Tools (F12 or Cmd + Option + I).
  3. Select the Network tab and refresh the page.
  4. Click the main request for your domain and inspect the Response Headers panel.

Automated Audits

A quick curl shows one response; it will not tell you whether a header value is weak or whether the rest of your setup (TLS, cookies, DNS records) is in order. Run the Sitecheckly Security Audit on your home page and your login page to check all six headers plus the rest of the passive security checks in one pass.

What to do next

  • Choose the configuration snippet above for your specific web server or hosting platform.
  • Update your server configuration or application repository and deploy the changes.
  • Run a scan using curl -I or the Sitecheckly Security Audit to verify all six security headers are present.

Frequently asked questions

Will adding a Content-Security-Policy break my website?

It can if configured too strictly. Test your CSP in report-only mode using Content-Security-Policy-Report-Only before enforcing it.

Is X-Frame-Options redundant if I already use Content-Security-Policy?

CSP frame-ancestors supersedes X-Frame-Options in modern browsers, but setting X-Frame-Options DENY or SAMEORIGIN ensures legacy browser protection.

Why is Strict-Transport-Security not taking effect on initial HTTP requests?

HSTS headers sent over unencrypted HTTP are ignored by browsers. You must serve HSTS over a valid HTTPS connection.


Want to see how your own site does? Run a free audit at sitecheckly.com.

Figures in this article come from Sitecheckly's own audit data; see the methodology.

Top comments (0)