HTTP Headers Check

Analyze the security, performance and caching headers of any website. Find vulnerabilities and room for optimization.

Analyzing HTTP headers...

What are HTTP headers?

HTTP headers are metadata sent with every HTTP request and response between the browser and the web server. They carry essential information about security, caching, compression and how the browser should handle the content. With our free HTTP headers check tool you can analyze all headers of any website and immediately see potential security risks and opportunities for optimization.

Headers are invisible to visitors but play a crucial role in how the modern web works. Every time your browser requests a website, dozens of headers are exchanged. The browser sends request headers (such as User-Agent, Accept-Language) and the server responds with response headers (such as Content-Type, Cache-Control, security headers). This exchange determines how content is displayed, cached and secured.

There are several categories of headers: security headers that protect against attacks, caching headers that improve performance, content headers that specify the type and encoding, and CORS headers that manage cross-origin requests. A thorough HTTP headers check gives you insight into all categories and shows where improvements are possible.

Why are security headers important?

Security headers are a crucial line of defense against common web attacks. They act as an extra security layer on top of your application code and protect both your website and your visitors. Even with perfectly secured code, missing security headers can leave you vulnerable to attacks. Our HTTP headers check tool checks all essential security headers and gives you concrete recommendations.

Security headers protect your website and visitors against:

  • XSS attacks (Cross-Site Scripting): with Content-Security-Policy (CSP) you prevent malicious scripts from running
  • Clickjacking: with X-Frame-Options you protect against invisible iframes that intercept clicks
  • Man-in-the-middle attacks: with HSTS you enforce encrypted HTTPS connections
  • MIME sniffing attacks: with X-Content-Type-Options you stop browsers from guessing content types
  • Cross-origin attacks: with COOP and CORP headers you isolate your website from other origins
  • Referrer leaks: with Referrer-Policy you control which information is passed on
  • Feature abuse: with Permissions-Policy you limit access to sensitive browser APIs

Without the right security headers your website is vulnerable to attacks, even if the code itself is secure. Security researchers and penetration testers always check the HTTP headers first to identify vulnerabilities. Big tech companies such as Google, Facebook and Microsoft enforce strict security header policies. With our tool you run the same checks as a professional security audit.

The most important security headers explained

Strict-Transport-Security (HSTS): This header forces browsers to connect to your website over HTTPS only. It prevents attackers from downgrading users to insecure HTTP traffic (SSL stripping attacks). Once a browser has received this header, it automatically upgrades all HTTP requests to HTTPS for the specified period, even if the user explicitly types http://. Recommended configuration: Strict-Transport-Security: max-age=31536000; includeSubDomains; preload. The max-age sets how long (in seconds) the browser should remember this, includeSubDomains applies it to all subdomains, and preload makes your site eligible for the HSTS preload list of browsers.

Content-Security-Policy (CSP): The most powerful security header against XSS attacks. CSP defines which sources (scripts, stylesheets, images, fonts) the browser may load and execute. This prevents injected malicious scripts from running, even if an attacker manages to inject code into your HTML. A basic CSP can look like this: Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'. For maximum security, avoid 'unsafe-inline' and use nonces or hashes.

X-Frame-Options: Prevents your website from being loaded in an iframe, which counters clickjacking attacks. In clickjacking, an attacker places your site in an invisible iframe over a fake interface, so users unknowingly perform actions on your site. Use X-Frame-Options: DENY to block all framing, or X-Frame-Options: SAMEORIGIN to only allow framing from your own domain. For modern browsers, Content-Security-Policy: frame-ancestors 'none' is a more flexible solution.

X-Content-Type-Options: Prevents MIME sniffing by telling the browser to respect the declared content type. Browsers sometimes try to "guess" the content type when it isn't clear, which can lead to security problems. A text/plain file could, for example, be interpreted as JavaScript if it contains executable code. Always use X-Content-Type-Options: nosniff to prevent this.

All security headers at a glance

A complete overview of all important security headers you can implement for maximum protection. All of these headers are checked by our HTTP headers check tool:

Header Purpose Recommended value
Strict-Transport-Security Enforces HTTPS connections max-age=31536000; includeSubDomains
Content-Security-Policy Defines allowed content sources default-src 'self'
X-Frame-Options Protects against clickjacking DENY or SAMEORIGIN
X-Content-Type-Options Prevents MIME sniffing nosniff
Referrer-Policy Controls referrer information strict-origin-when-cross-origin
Permissions-Policy Controls browser features geolocation=(), microphone=(), camera=()
Cross-Origin-Opener-Policy Isolates the browsing context same-origin
Cross-Origin-Resource-Policy Protects against cross-origin reads same-origin
Cross-Origin-Embedder-Policy Requires CORP for embedded resources require-corp

Content-Security-Policy in detail

Content-Security-Policy (CSP) is the most complex but also the most powerful security header. A well-configured CSP can almost completely eliminate XSS attacks. CSP works with directives that define which sources are allowed for each type of content.

Key CSP directives:

  • default-src: Default policy for all resource types. Other directives inherit from it.
  • script-src: Defines which JavaScript sources may be loaded and executed. Critical for XSS protection.
  • style-src: Controls which stylesheets and inline styles are allowed.
  • img-src: Defines from which sources images may be loaded.
  • font-src: Controls allowed font sources.
  • connect-src: Limits which URLs can be reached via fetch, XMLHttpRequest and WebSocket.
  • frame-src: Defines which URLs may be loaded in frames (similar to X-Frame-Options, but for embedded content).
  • media-src: Controls sources for audio and video elements.
  • object-src: Defines allowed sources for <object>, <embed> and <applet> elements.

CSP source values: Each directive accepts a list of allowed sources. You can use: 'self' (your own domain), 'none' (nothing allowed), specific domains such as https://cdn.example.com, 'unsafe-inline' (inline scripts/styles, insecure), 'unsafe-eval' (the eval() function, insecure), or nonces/hashes for specific inline scripts.

Nonces and hashes: For maximum security, avoid 'unsafe-inline' and use nonces or hashes instead. A nonce is a unique random value you generate per request and add to both the CSP header and the script tag: Content-Security-Policy: script-src 'nonce-abc123' and <script nonce="abc123">. Hashes are SHA-256/384/512 hashes of the exact script content: script-src 'sha256-xyz...'.

Report-URI and reporting: CSP can report violations to an endpoint: report-uri /csp-report or with the more modern report-to directive. This helps you monitor whether legitimate content is being blocked and whether there are attack attempts. Always start with Content-Security-Policy-Report-Only to test without blocking content.

Performance and caching headers

Besides security, our HTTP headers check also analyzes performance and caching headers that are crucial for fast websites:

  • Content-Encoding: Checks whether compression is active. Modern websites use gzip or brotli compression to shrink text files (HTML, CSS, JavaScript) by 70-80%. Content-Encoding: br (brotli) compresses better than gzip but is not supported by every browser. Content-Encoding: gzip is the safe choice that works everywhere. Without compression, pages load much more slowly, especially on mobile connections.
  • Cache-Control: Analyzes cache settings for optimal performance. This header determines how long browsers and CDNs may cache content. For static assets (CSS, JS, images) use Cache-Control: public, max-age=31536000, immutable to cache for a year. For dynamic content use Cache-Control: private, max-age=0, must-revalidate. The right cache strategy can reduce your server load by 90% and dramatically improve load times.
  • ETag: Checks whether cache validation is enabled. An ETag is a unique identifier for a specific version of a resource. When a browser has cached content, it sends the ETag in an If-None-Match header. If the content hasn't changed, the server responds with 304 Not Modified without sending the full content, which saves bandwidth.
  • Vary: Shows which request headers affect caching. Vary: Accept-Encoding tells caches to store both compressed and uncompressed versions. Vary: User-Agent caches different versions per browser type (often unnecessary and inefficient). For modern responsive sites, Vary: Accept-Encoding is usually enough.
  • Last-Modified: Indicates when content was last changed and works together with If-Modified-Since for cache validation.

The right caching headers can make your website significantly faster, reduce server load and drastically lower bandwidth costs. For WordPress hosting or other CMS platforms, good cache headers are essential for performance.

How do you improve your security score?

After an HTTP headers check, our tool gives a score per category and concrete recommendations. You can implement security headers in several ways:

1. Web server configuration: The most efficient method is to set headers at the web server level. For Apache (.htaccess), Nginx or IIS you can add headers that apply to all requests. This is faster than application-level headers because the web server adds them directly without running PHP or other application code. With VPS hosting you have full control over the web server configuration.

2. Application code: In PHP, Node.js, Python or other languages you can add headers programmatically. This gives more flexibility (for example different CSP policies per page) but is a bit slower. For WordPress sites you can add headers via functions.php or security plugins.

3. CDN/proxy level: Services such as Cloudflare, AWS CloudFront or other CDNs can add or modify headers. This is ideal for sites that already use a CDN. Cloudflare, for example, has simple "Transform Rules" to add headers.

4. CMS plugins: For WordPress there are excellent security plugins that configure headers automatically, such as Really Simple SSL, Security Headers or All In One WP Security. These plugins offer a user-friendly interface, so you don't have to edit configuration files.

Start with the essential headers (HSTS, CSP, X-Frame-Options, X-Content-Type-Options) and then expand with other security headers such as Referrer-Policy and Permissions-Policy. Always test thoroughly after adding headers; CSP in particular can block legitimate functionality if it is configured too strictly.

HTTP headers for WordPress

WordPress sites have specific considerations for HTTP headers. By default WordPress sends minimal security headers, so you need to add them yourself. There are three ways to add headers to WordPress:

Method 1: Via .htaccess (Apache): If your site runs on Apache (most web hosting plans), add these rules to the .htaccess file in your WordPress root:

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

Note: this CSP is relatively permissive with 'unsafe-inline' and 'unsafe-eval' because WordPress and many plugins use inline scripts. For a stricter CSP you may need to modify plugin code.

Method 2: Via wp-config.php: You can add headers in wp-config.php (add this before the "That's all, stop editing!" line):

header('Strict-Transport-Security: max-age=31536000; includeSubDomains');
header('X-Frame-Options: SAMEORIGIN');
header('X-Content-Type-Options: nosniff');
header('Referrer-Policy: strict-origin-when-cross-origin');

Method 3: Via functions.php: In your theme's functions.php (or a custom plugin), add this function:

function add_security_headers() {
  header('Strict-Transport-Security: max-age=31536000; includeSubDomains');
  header('X-Frame-Options: SAMEORIGIN');
  header('X-Content-Type-Options: nosniff');
}
add_action('send_headers', 'add_security_headers');

WordPress plugins: For a more user-friendly setup you can use plugins such as "HTTP Headers" (by Dimitar Ivanov) or "Security Headers", which offer a GUI for configuring headers. Really Simple SSL also adds some security headers automatically after activation. For WordPress hosting at Theory7 you can also contact support for help configuring headers.

HTTP headers for Apache and Nginx

Configuring HTTP headers differs between the Apache and Nginx web servers. Both are powerful options, but the syntax is different.

Apache configuration (.htaccess or httpd.conf):

For Apache you use the mod_headers module. Add the following to .htaccess or your virtual host configuration:

<IfModule mod_headers.c>
  # Security headers
  Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
  Header always set X-Frame-Options "SAMEORIGIN"
  Header always set X-Content-Type-Options "nosniff"
  Header always set Referrer-Policy "strict-origin-when-cross-origin"
  Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"
  Header always set Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self'"

  # Performance headers
  Header always set Cache-Control "public, max-age=31536000, immutable" "expr=%{REQUEST_URI} =~ m#\.(jpg|jpeg|png|gif|ico|css|js|woff|woff2)$#"
  Header always set Cache-Control "no-cache, no-store, must-revalidate" "expr=%{REQUEST_URI} =~ m#\.(html|php)$#"
</IfModule>

Make sure mod_headers is enabled: a2enmod headers and restart Apache.

Nginx configuration (nginx.conf or server block):

For Nginx you add headers in your server block or location context:

server {
  # Security headers
  add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
  add_header X-Frame-Options "SAMEORIGIN" always;
  add_header X-Content-Type-Options "nosniff" always;
  add_header Referrer-Policy "strict-origin-when-cross-origin" always;
  add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
  add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self'" always;

  # Static assets caching
  location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2)$ {
    add_header Cache-Control "public, max-age=31536000, immutable";
    expires 1y;
  }

  # Dynamic content
  location ~* \.(html|php)$ {
    add_header Cache-Control "no-cache, no-store, must-revalidate";
  }
}

After making changes, test the configuration with nginx -t and reload with nginx -s reload. The always keyword makes sure headers are also added to error responses (4xx, 5xx).

For both web servers: test thoroughly after adding headers with our HTTP headers check tool and check that your site still works correctly.

HTTP response codes

HTTP response codes (status codes) are sent via headers and indicate whether a request succeeded. Our tool shows the status code with every check. Common codes:

Code Meaning Explanation
200 OK Request succeeded, content is returned
301 Moved Permanently Permanent redirect, important for SEO. Browsers and search engines remember the new URL.
302 Found (Temporary Redirect) Temporary redirect, search engines keep indexing the original URL
304 Not Modified Content hasn't changed since the last request, the browser uses its cached version (saves bandwidth)
403 Forbidden Access denied, even with authentication. The server understands the request but refuses to carry it out.
404 Not Found The page or resource doesn't exist. Check your DNS configuration and server paths.
500 Internal Server Error General server error. Check the server logs for details.
502 Bad Gateway The server received an invalid response from an upstream server (e.g. PHP-FPM or a backend service)
503 Service Unavailable Server temporarily overloaded or under maintenance. Often sent with a Retry-After header.

The status code is in the first response header line, for example HTTP/1.1 200 OK. For redirects (301/302), the new location is given in the Location header. For errors, servers often send a Content-Type: text/html header with an error page. Correct status codes are crucial for SEO: use 301 for permanent redirects and make sure deleted pages return 404 (not 200).

CORS headers explained

CORS (Cross-Origin Resource Sharing) headers determine whether a website may load resources from another domain. Browsers block cross-origin requests by default for security reasons. CORS headers grant explicit permission.

Access-Control-Allow-Origin: The most important CORS header. It defines which origins have access to your resources. Access-Control-Allow-Origin: * allows all origins (dangerous for sensitive APIs), Access-Control-Allow-Origin: https://example.com allows only that specific domain. For APIs that are called from browsers (e.g. AJAX requests), this header must be set correctly.

Access-Control-Allow-Methods: Indicates which HTTP methods are allowed: Access-Control-Allow-Methods: GET, POST, PUT, DELETE. By default only GET and POST are allowed for simple requests.

Access-Control-Allow-Headers: Specifies which request headers the client may send: Access-Control-Allow-Headers: Content-Type, Authorization. Required for custom headers or authentication tokens.

Access-Control-Allow-Credentials: Determines whether cookies and authentication headers may be sent along: Access-Control-Allow-Credentials: true. If this is true, Access-Control-Allow-Origin must not be *.

Preflight requests: For "non-simple" requests (e.g. PUT, DELETE, or custom headers) the browser first sends an OPTIONS request (preflight) to check whether the request is allowed. The server must then respond with the correct CORS headers. A preflight response looks like this:

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400

The Access-Control-Max-Age header indicates how long (in seconds) the preflight response may be cached, which improves performance. For web APIs and SSL-secured endpoints, correct CORS headers are essential.

HTTP/2 and HTTP/3 headers

The modern HTTP/2 and HTTP/3 protocols handle headers more efficiently than HTTP/1.1, but header names and values largely stay the same. Our HTTP headers check works with all HTTP versions.

HTTP/2 improvements: HTTP/2 introduces HPACK header compression, which makes headers considerably smaller. Headers are encoded with Huffman encoding and a static/dynamic table of common headers. This saves bandwidth because Content-Type: text/html, for example, is encoded as a single byte instead of 24 bytes. HTTP/2 also supports multiplexing, so multiple requests share the same connection and header overhead is reduced further.

Pseudo-headers in HTTP/2: HTTP/2 uses special pseudo-headers that start with a colon: :method, :path, :scheme, :authority. These replace the first line of HTTP/1.1 requests (GET /path HTTP/1.1). For developers they are usually invisible because libraries handle this automatically.

HTTP/3 and QUIC: HTTP/3 builds on HTTP/2 but uses QUIC instead of TCP as its transport protocol. Headers work the same as in HTTP/2, but QPACK (an improved version of HPACK) offers even better compression and copes better with packet loss. HTTP/3 requires UDP instead of TCP, which reduces latency because no TCP handshake is needed.

Server Push (HTTP/2): HTTP/2 supports server push, where the server proactively sends resources before the browser asks for them. This works through the Link header with rel=preload: Link: </style.css>; rel=preload; as=style. Server push is experimental and not supported by all CDNs. HTTP/3 dropped push in favor of Early Hints (HTTP 103).

Migration considerations: When you migrate to HTTP/2 or HTTP/3, your security headers, caching headers and CORS headers keep working exactly the same. The protocols are backward compatible at the header level. You do need to configure your SSL/TLS certificates correctly, because HTTP/2 and HTTP/3 require HTTPS. For a VPS or dedicated servers you need nginx 1.9.5+ or Apache 2.4.17+ for HTTP/2 support.

Check which protocol your site uses with our tool: the HTTP version is shown in the response headers. HTTP/2 and HTTP/3 can improve load times by 20-50%, especially for sites with many small resources.

Frequently asked questions

What are HTTP headers?

HTTP headers are metadata sent with every HTTP request and response. They contain information about the server, caching, security and how the browser should handle the content. Headers are invisible to visitors but essential for how websites work and how secure they are.

Why are security headers important?

Security headers protect your website against common attacks such as XSS, clickjacking and man-in-the-middle attacks. Headers like HSTS, CSP and X-Frame-Options are essential for a secure website. Without these headers you are vulnerable, even if your code is secure.

What is HSTS (Strict-Transport-Security)?

HSTS is a security header that forces browsers to connect to your website over HTTPS only. This prevents attackers from downgrading users to insecure HTTP traffic. HSTS should have a long max-age (at least 1 year) and ideally include includeSubDomains.

What does Content-Security-Policy do?

Content-Security-Policy (CSP) is a powerful security header that protects against XSS attacks by defining which sources the browser may load. You can specify exactly which scripts, stylesheets and images are allowed. CSP is one of the most important security headers.

How do I improve my security headers score?

Add essential security headers such as HSTS, Content-Security-Policy, X-Frame-Options and X-Content-Type-Options. You can set these in your web server configuration (Apache, Nginx) or in your application. Start with the basics and expand from there. Our tool gives concrete recommendations for every missing header.