HTTP Headers Explained: Security & Best Practices

Master HTTP headers to improve security, performance, and SEO for your web applications

Table of Contents

What Are HTTP Headers?

HTTP headers are key-value pairs sent between a client (typically a web browser) and a server during HTTP requests and responses. They provide essential metadata about the request or response, including content type, caching instructions, security policies, and server information.

Think of HTTP headers as the envelope and postage information on a letter. While the body of the HTTP message contains the actual content (the letter itself), headers provide crucial context about how to handle that content.

Request vs Response Headers

Request Headers are sent from the client to the server and include information like:

Response Headers are sent from the server back to the client and include:

Why Headers Matter

Properly configured HTTP headers can protect against common web vulnerabilities, improve performance through caching, enhance SEO, and provide a better user experience. Missing or misconfigured headers are among the top security issues found in web application security audits.

Essential Security Headers

Security headers are specialized HTTP response headers that tell browsers how to behave when handling your site's content. They're your first line of defense against many common web attacks.

Content-Security-Policy (CSP)

The Content-Security-Policy header prevents Cross-Site Scripting (XSS) attacks by specifying which sources of content are allowed to load on your page.

Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' https://cdn.example.com; img-src 'self' data: https:; style-src 'self' 'unsafe-inline';

How it works: CSP creates an allow-list of trusted content sources. Even if an attacker injects malicious code, the browser won't execute it unless it comes from an allowed source.

Common directives:

CSP Implementation Warning

Implementing CSP on an existing site can break functionality if not done carefully. Start with Content-Security-Policy-Report-Only header to monitor violations without blocking content, then migrate to enforcement once issues are resolved.

Strict-Transport-Security (HSTS)

HSTS forces browsers to only connect to your site over HTTPS, preventing man-in-the-middle attacks and SSL stripping. For complete HTTPS security, also ensure your SSL certificates are properly configured.

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

Key parameters:

HSTS Preload: Submit your domain to hstspreload.org to be hardcoded into browsers, providing protection on the very first visit.

X-Frame-Options

Protects against clickjacking attacks by controlling whether your site can be embedded in iframes.

X-Frame-Options: DENY

Options:

Modern Alternative

While X-Frame-Options is still widely supported, the modern approach is using CSP's frame-ancestors directive, which provides more granular control: Content-Security-Policy: frame-ancestors 'self' https://trusted.com

X-Content-Type-Options

Prevents MIME type sniffing, which can lead to security vulnerabilities.

X-Content-Type-Options: nosniff

This simple header tells browsers to trust the Content-Type header and not try to guess the content type. Without it, a browser might execute a file declared as text/plain as JavaScript if it looks like JavaScript.

Referrer-Policy

Controls how much referrer information is included with requests.

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

Common policies:

Permissions-Policy

Controls which browser features and APIs can be used on your site.

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

This allows you to disable potentially invasive features that your site doesn't use, reducing attack surface.

X-XSS-Protection

Legacy header that enabled the browser's XSS filter. Now largely deprecated in favor of CSP.

X-XSS-Protection: 0

Deprecated Header

Modern browsers have removed XSS auditors due to bypass techniques and false positives. The recommended value is 0 to disable it, relying instead on Content-Security-Policy for XSS protection.

How to Analyze Response Headers

Understanding how to inspect and analyze HTTP headers is crucial for debugging, security audits, and optimization.

Using Browser Developer Tools

The easiest way to view headers:

  1. Open Developer Tools (F12 or Ctrl+Shift+I)
  2. Go to the Network tab
  3. Reload the page
  4. Click on any request
  5. View the Headers section

Using Command Line Tools

For automation and scripting, command-line tools are invaluable:

# View headers with curl
curl -I https://example.com

# View headers with verbose output
curl -v https://example.com

# View specific header
curl -I https://example.com | grep -i "content-security-policy"

Using HTTP Tiger's Header Checker

The most comprehensive way to analyze headers is using a dedicated tool that checks for security best practices:

How to Use the Tool

  1. Visit httptiger.com/header-checker.html
  2. Enter your website URL
  3. Click "Check Headers" to analyze the response
  4. Review the security score and recommendations
  5. Get specific implementation guidance for missing headers

Common Header Misconfigurations

Even experienced developers make these mistakes. Here's what to avoid:

1. Missing Security Headers Entirely

The Problem: Many sites ship with default server configurations that include minimal security headers.

The Fix: Implement at minimum: CSP, HSTS, X-Content-Type-Options, and X-Frame-Options.

2. Overly Permissive CSP

❌ Bad: Content-Security-Policy: default-src *; script-src * 'unsafe-inline' 'unsafe-eval'

This CSP allows everything and provides zero protection.

✓ Good: Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com

3. Short HSTS max-age

❌ Bad: Strict-Transport-Security: max-age=86400

A 1-day max-age means users are only protected for 24 hours between visits.

✓ Good: Strict-Transport-Security: max-age=31536000; includeSubDomains

4. Exposing Server Information

❌ Bad: Server: Apache/2.4.41 (Ubuntu) OpenSSL/1.1.1f

This tells attackers exactly what server version you're running, making targeted attacks easier.

✓ Good: Server: Apache (or remove the header entirely)

5. Weak Cache-Control for Sensitive Data

❌ Bad: Cache-Control: public, max-age=31536000 (on a user dashboard page)

This could cache sensitive user data in browsers or proxies for a year.

✓ Good: Cache-Control: no-store, no-cache, must-revalidate, private

6. Incorrect Content-Type

Serving JavaScript files as text/plain or JSON as text/html can cause security issues and functional problems.

Implementation Guide

How to implement security headers depends on your web server or hosting platform.

Apache (.htaccess)

# Enable mod_headers

    # HSTS
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"

    # CSP
    Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://cdn.example.com; img-src 'self' data: https:; style-src 'self' 'unsafe-inline';"

    # X-Frame-Options
    Header always set X-Frame-Options "SAMEORIGIN"

    # X-Content-Type-Options
    Header always set X-Content-Type-Options "nosniff"

    # Referrer-Policy
    Header always set Referrer-Policy "strict-origin-when-cross-origin"

    # Permissions-Policy
    Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"

Nginx

# In your server block
server {
    # HSTS
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

    # CSP
    add_header Content-Security-Policy "default-src 'self'; script-src 'self' https://cdn.example.com;" always;

    # X-Frame-Options
    add_header X-Frame-Options "SAMEORIGIN" always;

    # X-Content-Type-Options
    add_header X-Content-Type-Options "nosniff" always;

    # Referrer-Policy
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
}

Node.js/Express

const helmet = require('helmet');
const app = express();

// Use helmet middleware for security headers
app.use(helmet({
    contentSecurityPolicy: {
        directives: {
            defaultSrc: ["'self'"],
            scriptSrc: ["'self'", "https://cdn.example.com"],
            styleSrc: ["'self'", "'unsafe-inline'"],
            imgSrc: ["'self'", "data:", "https:"]
        }
    },
    hsts: {
        maxAge: 31536000,
        includeSubDomains: true,
        preload: true
    }
}));

CloudFront (AWS)

Use Lambda@Edge or CloudFront Functions to add headers:

// Lambda@Edge (origin response)
exports.handler = (event, context, callback) => {
    const response = event.Records[0].cf.response;
    const headers = response.headers;

    headers['strict-transport-security'] = [{
        key: 'Strict-Transport-Security',
        value: 'max-age=31536000; includeSubDomains; preload'
    }];

    headers['x-content-type-options'] = [{
        key: 'X-Content-Type-Options',
        value: 'nosniff'
    }];

    callback(null, response);
};

Testing Your Headers

After implementing security headers, thorough testing is essential to ensure they're working correctly and not breaking functionality.

Automated Testing Tools

  1. HTTP Tiger Header Checker - httptiger.com/header-checker.html - Comprehensive header analysis with security scoring
  2. SecurityHeaders.com - Quick security header scan with letter grades
  3. Mozilla Observatory - Detailed security analysis including headers and TLS configuration

Testing CSP

CSP is particularly tricky to get right. Use these strategies:

  1. Start with Report-Only mode:
    Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-violation-report
  2. Monitor violation reports to identify legitimate resources being blocked
  3. Adjust policy based on reports
  4. Switch to enforcement mode once confident

Testing HSTS

HSTS testing checklist:

Security Header Checklist

A properly configured site should have:

  • Content-Security-Policy (restrictive policy)
  • Strict-Transport-Security (1 year minimum)
  • X-Content-Type-Options: nosniff
  • X-Frame-Options or CSP frame-ancestors
  • Referrer-Policy (strict-origin-when-cross-origin)
  • Permissions-Policy (disabling unused features)

Conclusion

HTTP headers are a powerful tool for enhancing your website's security, performance, and functionality. While they may seem technical, implementing proper headers is one of the highest-impact, lowest-effort security improvements you can make.

Start with the essential security headers (CSP, HSTS, X-Content-Type-Options, X-Frame-Options), test thoroughly, and gradually refine your configuration. Regular audits using automated tools will help you maintain a strong security posture over time.

Check Your HTTP Headers Now

Use HTTP Tiger's free header checker to analyze your website's headers and get specific recommendations.

Analyze Headers →