2026-04-17•Security

HTTP Security Headers: Your Site Is Failing Without You Knowing

Most websites score an F on security header audits — not because they were hacked, but because they never configured basic protections. Learn the 6 essential headers, how to set up HSTS, CSP, and X-Frame-Options, and use our checklist to reach an A+ grade.

There's a security test anyone can run on their website right now. The result appears in seconds: a grade from A+ to F. And the vast majority of sites on the internet — including those from large companies — score an F or a D.

Not because they were hacked. Not because they have vulnerabilities in their code. But because they never configured basic protections that have existed for years, are completely free, and take less than 5 minutes to enable.

These are HTTP security headers. And your site is probably missing them right now.

What Are HTTP Security Headers

Every time a browser accesses a page, the server responds with two components: the page content (HTML, CSS, JS) and a set of HTTP headers — invisible metadata that instructs the browser on how to behave.

Most developers are familiar with headers like Content-Type or Cache-Control. But there's an entire category of headers dedicated exclusively to security, telling the browser things like:

  • "Never load this site over HTTP, only HTTPS"
  • "Don't allow this page to be displayed inside an iframe"
  • "Block any script that doesn't come from my own servers"

When these headers are absent, the browser falls back to permissive default behaviors — opening the door to clickjacking, script injection, data theft, and a range of attacks with decades of documented history.

The good news: configuring these headers doesn't require rewriting any code. It's a single line in your web server or CDN configuration.

The 6 Essential Security Headers (and How to Configure Each)

1. HSTS — HTTP Strict Transport Security

What it protects against: Forces the browser to always use HTTPS, eliminating downgrade attacks where an attacker intercepts the connection and degrades it to unencrypted HTTP.

The risk without it: Even if your site uses HTTPS, a user who types mysite.com makes the first request over HTTP before being redirected. That millisecond is enough for a man-in-the-middle attack.

How to configure:

Nginx:

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

Apache:

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

Cloudflare: Enable under SSL/TLS → Edge Certificates → HTTP Strict Transport Security (HSTS).

The max-age=31536000 sets a 1-year validity period. The preload flag allows your domain to be included in browsers' built-in preload lists — after that, not even the first HTTP request is made.

2. Content-Security-Policy (CSP)

What it protects against: Defines exactly which content sources are allowed — scripts, styles, images, fonts, iframes. It's the primary defense against XSS (Cross-Site Scripting) attacks.

The risk without it: If an attacker manages to inject a malicious <script> into your page (via a comment, form field, or compromised dependency), the browser executes it without question.

How to configure:

Nginx:

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

Apache:

Header always set Content-Security-Policy "default-src 'self'; script-src 'self' https://trusted-cdn.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; frame-ancestors 'none';"

Cloudflare: Add via Rules → Transform Rules → Response Header Modification.

CSP is the most complex header to configure correctly, as it varies based on what your site loads. Use Content-Security-Policy-Report-Only mode first to identify blocks without breaking the site.

3. X-Frame-Options

What it protects against: Prevents your page from being loaded inside an <iframe> on another domain, blocking clickjacking attacks — where an attacker overlays your invisible page on top of another to capture clicks.

The risk without it: A malicious site can create a transparent iframe with your login page overlaid on a "Win a prize" button. The user enters their credentials without realizing it.

How to configure:

Nginx:

add_header X-Frame-Options "DENY" always;

Apache:

Header always set X-Frame-Options "DENY"

Cloudflare: Enable under SSL/TLS → Edge Certificates or via Transform Rules.

Use DENY to block completely, or SAMEORIGIN if you need to load your own page in internal iframes. Note: if you already use CSP with frame-ancestors, it takes precedence in modern browsers — but keep X-Frame-Options for legacy browser support.

4. X-Content-Type-Options

What it protects against: Prevents the browser from "guessing" the content type of a file when the server doesn't specify it clearly. Without this header, a .txt file containing JavaScript could be executed as a script.

The risk without it: An attacker who manages to upload a file to your server (an image, for example) can craft the content so that the browser interprets it as executable JavaScript.

How to configure:

Nginx:

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

Apache:

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

Cloudflare: Available in Managed Headers or via Transform Rules.

This is the simplest header on the list. One word, zero risk of breaking functionality, immediate protection.

5. Referrer-Policy

What it protects against: Controls how much of the originating URL is sent when a user clicks a link to another site. Without control, the full URL — including session parameters, tokens, and sensitive data — can leak to third parties.

The risk without it: If your dashboard URL is app.mysite.com/dashboard?token=abc123 and you have a link to an external blog, that token can appear in the external site's access logs.

How to configure:

Nginx:

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

Apache:

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

strict-origin-when-cross-origin is the ideal balance: sends the full URL for same-domain requests, but only the origin domain (without path or parameters) for cross-origin requests.

6. Permissions-Policy

What it protects against: Defines which browser APIs your site can use — camera, microphone, geolocation, notifications, accelerometer. Restricts access even if a malicious script is injected.

The risk without it: A third-party script (widget, analytics, advertising) can request access to the user's camera or geolocation on behalf of your domain.

How to configure:

Nginx:

add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=(), usb=()" always;

Apache:

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

The () syntax means "no one has access." If your site uses geolocation, replace it with geolocation=(self).

How to Check Your Site's Grade Right Now

Configuring the headers is half the work. The other half is verifying they're being sent correctly — on every page, including subdomains.

FlashMon's Security Headers Checker analyzes any URL and returns:

  • A grade from A+ to F based on the headers present and missing
  • Which headers are correctly configured
  • Which are missing and what risk each absence carries
  • Full analysis of CSP, HSTS, X-Frame-Options, and all others

The analysis is free and instant. You can also combine it with the SSL Checker to ensure your TLS certificate is valid, and the HTTP Status Checker to confirm that HTTP→HTTPS redirects are working before HSTS kicks in.

Quick Implementation Checklist

Use this list before publishing any site to production:

Required headers (minimum grade B without them):

  • Strict-Transport-Security with max-age of at least 6 months
  • X-Frame-Options: DENY or SAMEORIGIN
  • X-Content-Type-Options: nosniff

Recommended headers (the difference between B and A+):

  • Content-Security-Policy with default-src 'self' as a baseline
  • Referrer-Policy: strict-origin-when-cross-origin
  • Permissions-Policy restricting camera, microphone, and geolocation

Post-configuration checks:

  • Run FlashMon's Security Headers Checker on the homepage
  • Test on internal pages too (blog, dashboard, login)
  • Check subdomains separately — www and api have independent headers
  • Confirm HTTPS is working before enabling HSTS with preload
  • Monitor CSP errors in the browser console after deploy

Common pitfalls:

  • Headers set on the server but overridden by the CDN (or vice versa)
  • CSP blocking legitimate analytics or chat scripts — test in staging first
  • HSTS activated before verifying HTTPS works — this can make your site unreachable

Security isn't binary. There's no such thing as a "100% secure" website, but there is a website that makes an attacker's job harder versus one that makes it easier. Configuring security headers is one of the few measures where the effort is minimal and the impact is immediate.

Five minutes of configuration. An A+ grade on the audit. And the peace of mind that the basic protections are in place.

Check your site's security grade now →


Keep going

Written by FlashMon Team

Monitoring & Reliability Specialists

Liked this article?

Sign up for our newsletter to get the latest monitoring tips and tricks.

Subscribe