How to Check Website Security Headers

HTTP security headers protect websites from XSS, clickjacking, MIME sniffing, and other attacks. This guide shows how to check them and what to do when they are missing.


HTTP security headers are your website's first line of defence against a range of browser-based attacks. But many websites are missing key headers — or have them misconfigured. This guide shows you how to check every important security header, what each one should say, and how to fix missing or incorrect ones.

Security Headers Every Website Should Have

HeaderProtects AgainstRecommended Value
Strict-Transport-SecurityHTTP downgrade attacksmax-age=31536000; includeSubDomains
Content-Security-PolicyXSS, data injectionSite-specific policy (see CSP guide)
X-Frame-OptionsClickjackingDENY or SAMEORIGIN
X-Content-Type-OptionsMIME type sniffingnosniff
Referrer-PolicyInformation leakage via Referer headerstrict-origin-when-cross-origin
Permissions-PolicyUnwanted browser feature accessRestrict unneeded features

Method 1: ShowDNS Security Headers Tool

The ShowDNS Security Headers checker is the fastest way to check all security headers at once:

  1. Go to showdns.net/security-headers.
  2. Enter your website URL.
  3. Click Check.
  4. The tool shows all present and missing security headers with a grade and recommendations.

Method 2: Using curl

curl -I fetches only the HTTP headers (HEAD request):

bash
# Check all response headers curl -I https://example.com # Filter for security headers only curl -I https://example.com 2>/dev/null | grep -iE "strict-transport|content-security|x-frame|x-content-type|referrer-policy|permissions-policy" # Follow redirects (important to check the final response) curl -IL https://example.com

Example output:

text
HTTP/2 200 strict-transport-security: max-age=31536000; includeSubDomains; preload content-security-policy: default-src 'self'; script-src 'self' https://cdn.example.com x-frame-options: DENY x-content-type-options: nosniff referrer-policy: strict-origin-when-cross-origin

Method 3: Browser DevTools

  1. Open your website in Chrome or Firefox.
  2. Right-click anywhere on the page and select Inspect.
  3. Go to the Network tab.
  4. Reload the page (F5).
  5. Click on the first request (the HTML document, usually the domain name).
  6. In the Response Headers section, look for security headers.
Check the final request, not redirectsIf your site redirects from HTTP to HTTPS, click on the HTTPS request (not the 301 redirect) to see the security headers on the actual page response. Security headers on redirect responses may not offer the same protection.

What to Do When Headers Are Missing

Missing Strict-Transport-Security

Add to your web server config. See the How to Enable HSTS guide.

nginx
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

Missing X-Frame-Options

nginx
add_header X-Frame-Options "DENY" always;
apache
Header always set X-Frame-Options "DENY"

Missing X-Content-Type-Options

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

Missing Referrer-Policy

nginx
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

Missing Content-Security-Policy

Start with report-only mode. See the How to Configure CSP guide.

Complete Nginx Security Headers Block

nginx
# Add to your server block (443/HTTPS) add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" 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; add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; frame-ancestors 'none';" always;

Complete Apache Security Headers Block

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" Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()" 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'; frame-ancestors 'none'"

Frequently Asked Questions

Do security headers affect website performance?

No. Security headers are small additions to the HTTP response. They add negligible overhead and do not affect page load speed or performance metrics.

Should I add security headers to HTTP responses too?

Most security headers (HSTS, CSP, etc.) only make sense on HTTPS responses. However, including them on HTTP responses as well doesn't hurt. For HSTS specifically, browsers ignore the header over HTTP — it must be received over HTTPS to take effect.

Why is my security header present in DevTools but not in curl?

Some headers are added by JavaScript (client-side) and only appear in browser DevTools, not in raw HTTP responses. Security headers must be set server-side to be effective — client-side JavaScript cannot add headers to HTTP responses.

Related Articles