1. Library
  2. Computer Networks
  3. Tools and Commands
  4. Online Tools

Updated 8 hours ago

HTTP security headers protect against common web attacks, yet most websites implement them poorly or not at all. The Security Headers service at securityheaders.com scans your site's HTTP responses, grades your implementation, and shows exactly what's missing.

What Security Headers Actually Do

Security headers are HTTP response headers that instruct browsers to enable specific protections. Unlike server-side security, these headers leverage the browser itself as a defense layer.

Here's the mental shift: you're not configuring a server. You're telling every browser that visits: "Here's how to protect my users."

The browser can block scripts from untrusted sources, refuse to load your site in a frame, enforce HTTPS-only connections, and more—but only if you tell it to. Without these headers, browsers use permissive defaults that attackers exploit.

Using securityheaders.com

Visit https://securityheaders.com, enter your URL, and within seconds you'll have a letter grade (A+ to F) and a detailed breakdown of what's present, what's missing, and what's misconfigured.

No registration required. Results are public by default—useful for sharing with developers or proving to stakeholders that work is needed.

The Grading System

A+ Grade: All major security headers present with strong policies. This is achievable for any site willing to invest the configuration time.

A Grade: Strong implementation with minor gaps. Perhaps a slightly permissive CSP or missing an optional header.

B-D Grades: Partial implementation. Some headers present, others missing or weak.

F Grade: Little to no security header implementation. Unfortunately common.

Content-Security-Policy (CSP)

CSP is the most powerful security header—and the most complex. It tells browsers exactly which sources can load scripts, styles, images, and other resources on your page.

The core idea: if an attacker injects a script tag pointing to their malicious server, the browser blocks it because that server isn't on your approved list.

A basic policy:

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

This says: load resources only from my origin by default, allow scripts from my origin and my CDN, allow styles from my origin (plus inline styles), allow images from my origin and HTTPS sources, and never let anyone frame my site.

CSP is hard because modern sites load resources from everywhere—analytics, fonts, ads, widgets. Start with report-only mode:

Content-Security-Policy-Report-Only: default-src 'self'

This logs violations without blocking anything. Watch the console, see what your site actually needs, then build a real policy.

Strict-Transport-Security (HSTS)

HSTS tells browsers: "Only ever connect to me over HTTPS. If someone tries HTTP, upgrade it automatically. Don't even ask."

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

max-age: How long (in seconds) to enforce this. One year is standard for production.

includeSubDomains: Apply to all subdomains. Be careful—this breaks any subdomain still on HTTP.

preload: Submit to browser preload lists for protection on first visit. Hard to undo.

Warning: only enable HSTS after confirming HTTPS works everywhere on your site. Once set, browsers won't touch HTTP for the max-age duration—even if HTTPS breaks.

X-Frame-Options

Prevents clickjacking—where attackers embed your site in an invisible iframe and trick users into clicking things they can't see.

X-Frame-Options: DENY

DENY: No one can frame your site. Use this unless you specifically need framing.

SAMEORIGIN: Only your own pages can frame your site.

For more control, CSP's frame-ancestors directive is the modern replacement:

Content-Security-Policy: frame-ancestors 'none'

X-Content-Type-Options

Browsers sometimes "sniff" content types, ignoring what the server declares and guessing based on content. Attackers exploit this—upload a file that looks like an image but contains script, trick the browser into executing it.

X-Content-Type-Options: nosniff

One directive, no options. Just add it.

Referrer-Policy

Controls what information browsers send in the Referer header when users click links from your site.

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

This sends full referrer info for same-origin navigation, just the origin (not the full URL) for cross-origin HTTPS, and nothing when downgrading to HTTP. A reasonable default balancing privacy and functionality.

no-referrer: Send nothing. Maximum privacy, but breaks some analytics and affiliate tracking.

same-origin: Only send referrer for same-origin requests.

Permissions-Policy

Controls which browser features your site can use—geolocation, camera, microphone, payment APIs, and more.

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

Empty parentheses mean "disabled for everyone." If you don't use these features, disable them. This prevents third-party scripts from accessing capabilities you never intended to grant.

To allow specific origins:

Permissions-Policy: geolocation=(self "https://maps.example.com"), camera=()

X-XSS-Protection

Here's a strange one: this header enabled browser XSS filters, but the modern recommendation is to explicitly disable it:

X-XSS-Protection: 0

Why disable a security feature? Because XSS auditors have caused security issues themselves—they've been exploited to leak information and break sites. Rely on CSP for XSS protection instead. Some scanners still check for this header, so explicitly disabling is better than omitting.

Implementation

Web Server Configuration (Recommended)

nginx:

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" 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;

Apache:

Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
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"

Application-Level: Most frameworks provide middleware for setting headers. Useful when you can't modify server config or need per-route policies.

CDN/Proxy: Services like Cloudflare can add headers. Convenient but creates third-party dependency.

Testing and Debugging

After implementation, retest with securityheaders.com. Common issues:

  • Configuration syntax errors causing headers not to appear
  • Headers on HTML pages but not API endpoints
  • Conflicting headers from different configuration layers
  • Policies too restrictive, breaking functionality

Browser developer tools are essential for debugging. The Console shows CSP violations with specific details: what was blocked, which directive blocked it, and what was attempted. The Network tab shows all response headers.

Implementation Order

Don't chase a perfect score immediately. Start with what won't break anything:

  1. X-Content-Type-Options: nosniff — Safe, simple, one directive
  2. X-Frame-Options: DENY — Unless you need framing
  3. Referrer-Policy: strict-origin-when-cross-origin — Sensible default
  4. HSTS — After confirming HTTPS works everywhere
  5. CSP — Start report-only, analyze, refine, then enforce

This gets you to a B or better quickly, with the complex work (CSP) done carefully at the end.

Ongoing Maintenance

Security header standards evolve. New attacks emerge. Browsers add new protections. Periodically retest and review guidance.

Configuration changes, server updates, and CDN modifications can inadvertently remove headers. Automated monitoring that alerts on changes is worth considering.

Frequently Asked Questions About Security Headers

Was this page helpful?

😔
🤨
😃