Skip to main content
Security
Published 13 min read

HTTP Security Headers Explained: A Practical Developer Guide

A handful of response headers tell the browser how to defend the page they came with. Here's what each one actually does.

A browser doesn't know, by default, whether a page should be embeddable in a frame, whether inline scripts should be trusted, or whether the connection should ever fall back to plain HTTP. HTTP security headers are how a server tells it. This is a map of the headers that matter most, and what each one is actually responsible for.

The header lineup at a glance

HeaderControls
Content-Security-PolicyWhich sources scripts, styles, images, and other resources may load from
Strict-Transport-SecurityForces HTTPS-only connections for a set period
X-Content-Type-OptionsPrevents the browser from guessing a response's content type
X-Frame-OptionsControls whether the page can be embedded in a frame (legacy clickjacking control)
Referrer-PolicyControls how much of the referring URL is sent to other origins
Permissions-PolicyRestricts which browser features (camera, microphone, geolocation) can be used
Access-Control-Allow-Origin (CORS)Whether a cross-origin script can read this response
Cross-Origin-Opener-PolicyIsolates the page's browsing context from cross-origin windows
Cross-Origin-Embedder-PolicyRequires embedded cross-origin resources to explicitly opt in
Cross-Origin-Resource-PolicyControls which sites can embed this specific resource
Set-Cookie attributesSecure, HttpOnly, and SameSite control how cookies can be accessed and sent

Content-Security-Policy

CSP lets a server declare an allow-list for where scripts, styles, images, and other resources are permitted to load from. A tight policy can reduce the impact of certain classes of injection and XSS attacks - if an attacker manages to inject a <script> tag, a well-configured CSP can block it from executing or from loading an external payload.

Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'

For the full breakdown of directives and common mistakes, see Content-Security-Policy (CSP) Explained With Examples.

Strict-Transport-Security (HSTS)

HSTS tells the browser: once you've connected to this site over HTTPS, never fall back to plain HTTP for the duration specified, even if a user types http:// or clicks an old link.

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

See What Is HSTS? Strict-Transport-Security Explained for a full breakdown of max-age, includeSubDomains, and preload.

X-Content-Type-Options

Set to nosniff, this stops the browser from trying to guess a response's content type based on its content rather than trusting the declared Content-Type - a behavior that's historically enabled certain content-type confusion attacks.

X-Content-Type-Options: nosniff

X-Frame-Options

Controls whether the page can be loaded inside a <frame> or <iframe> on another site - the classic clickjacking defense. CSP's frame-ancestors directive is the modern replacement with more flexibility, but X-Frame-Options is still worth setting for older browsers. See X-Frame-Options vs CSP frame-ancestors: What's the Difference? for the comparison.

Referrer-Policy

Controls how much of the current page's URL is sent in the Referer header when a user navigates to (or a resource loads from) another origin. strict-origin-when-cross-origin is a widely-recommended modern default - it sends the full URL only to same-origin destinations.

Permissions-Policy

Restricts which powerful browser features - camera, microphone, geolocation, payment APIs - can be used by the page or anything embedded in it.

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

CORS headers

CORS isn't one header but a set of them, governing whether a script running on a different origin can read this response. The Access-Control-Allow-Origin header is the core piece - see CORS Explained for the full mechanism and the wildcard-plus-credentials mistake that comes up constantly.

COOP, COEP, and CORP

These three headers work together to isolate a page from cross-origin content at the browser level - relevant for mitigating speculative-execution-style attacks (like Spectre) and required for certain powerful APIs (like SharedArrayBuffer). They're not required for every site, but worth understanding if you're building something performance-sensitive that needs that isolation.

Not response headers in the traditional sense, but Set-Cookie carries its own security-relevant attributes: Secure (HTTPS only), HttpOnly (not readable by JavaScript), and SameSite (controls cross-site sending behavior). Misconfigured cookies are one of the most common findings in any header audit.

Checking your own headers

You can pull a site's response headers from your browser's DevTools Network tab, or with curl -I https://example.com from a terminal. Paste the response headers into the HTTP Security Headers Analyzer to get a scored breakdown of what's present, what's missing, and what's misconfigured - entirely in your browser, without needing to provide a URL.

A note on scope

Security headers are one layer of a much larger picture - they reduce the impact of certain attack classes when configured well, but they don't replace input validation, authentication, authorization, or any of the other fundamentals. Treat header analysis as a configuration check, not a full security audit.

Summary

Each of these headers controls one specific piece of browser behavior - script sources, transport security, framing, referrer leakage, feature access, or cross-origin isolation. None of them is universally required for every site, but understanding what each one actually does is what lets you configure the ones that matter for yours.

Frequently asked questions

What are HTTP security headers?
They're response headers a server sends that instruct the browser to enable specific protections - restricting where scripts can load from, forcing HTTPS, preventing a page from being framed, and more. The browser enforces them; the server just declares them.
Which HTTP security headers should I use?
There's no single universal list, but a solid baseline for most sites includes a tailored Content-Security-Policy, Strict-Transport-Security, X-Content-Type-Options: nosniff, a clickjacking control, and a modern Referrer-Policy - adjusted to what your site actually needs.
Is CSP required?
Not required by any browser, but it's one of the highest-value headers you can configure, since it can reduce the impact of certain injection and XSS attack classes when set up correctly.
What does HSTS do?
Strict-Transport-Security tells the browser to only ever connect to a site over HTTPS for a set period, closing the window for downgrade attacks that rely on intercepting an initial plain-HTTP connection.
What does X-Content-Type-Options do?
Setting it to nosniff tells the browser not to guess ("sniff") a response's content type based on its content, which prevents certain content-type confusion attacks.
How can I check security headers on a site?
Grab the response headers from your browser's DevTools Network tab (or curl -I), and paste them into a header analyzer to see what's present, what's missing, and what might be misconfigured.

The tool that pairs with this guide.

Did this help you tighten your security headers?

If these free developer tools save you time, consider buying me a byte. Your support helps keep DevCraftKit free and growing.

Buy me a byte 💾