Content Security Policy and Security Headers Explained

Content Security Policy and Security Headers Explained

Most web security advice focuses on code: validate input, escape output, hash passwords and keep dependencies updated. All of that matters. But there is another layer that many small web projects skip entirely, even though it is relatively cheap to add: HTTP security headers.

Security headers are instructions your server sends to the browser along with each page. They tell the browser how to behave, such as which scripts it may run, whether the site can be shown inside a frame on another domain and whether it should always use HTTPS. Set up well, they make many common attacks much harder. Set up carelessly, they can break your site. This guide explains the main headers and a safe way to introduce them.

Green and silver padlock on yellow surface

Why Headers Matter

Browsers are powerful and permissive by default. Without guidance, they will load scripts from almost anywhere, allow your pages to be framed by other sites and accept older, less secure behaviours for compatibility. Attackers rely on those defaults.

Security headers narrow what the browser will accept. They do not replace secure code, but they act as a safety net. If a cross-site scripting bug slips through, a good Content Security Policy may stop the injected script from running. If someone tries to trick users by framing your login page, a frame-related header can block it. Our overview of the OWASP Top 10 explains the attacks these headers help defend against.

The Key Headers to Know

These are the headers most small web apps should consider:

  • Content-Security-Policy (CSP): controls where scripts, styles, images, fonts and other resources may load from
  • Strict-Transport-Security (HSTS): tells browsers to always use HTTPS for your domain for a set period
  • X-Content-Type-Options: with the value nosniff, stops browsers guessing file types, which reduces some attack risks
  • Frame protection: the frame-ancestors directive in CSP, or the older X-Frame-Options header, controls whether other sites can embed your pages
  • Referrer-Policy: limits how much of your URL is shared with other sites when users click links
  • Permissions-Policy: restricts access to browser features such as camera, microphone and location

Not every site needs every header configured in the strictest way, but each one is worth a deliberate decision.

Man facing three computer monitors while sitting

Content Security Policy in Practice

CSP is the most powerful header and the one most likely to cause breakage. A policy lists allowed sources for each resource type. For example, you might allow scripts only from your own domain and a specific analytics provider, and block inline scripts entirely.

The challenge is that many sites load resources from places developers have forgotten about: chat widgets, tag managers, payment scripts, embedded videos, fonts and maps. A strict policy that misses one of these will silently break that feature. Inline scripts and event handlers written directly in HTML are another common obstacle, since strict policies block them unless you use nonces or hashes.

Tip: start CSP in report-only mode. The browser reports what would have been blocked without actually blocking it, so you can build a policy that matches your real site before enforcing it.

A Safe Rollout Plan

Introduce headers gradually rather than all at once:

  1. Add the low-risk headers first, such as nosniff, a sensible Referrer-Policy and frame protection.
  2. Make sure HTTPS works on every page and subdomain before enabling HSTS, and start with a short duration.
  3. Deploy CSP in report-only mode and collect violation reports for a while.
  4. Adjust the policy, remove unnecessary third-party scripts and move inline scripts into files where practical.
  5. Switch CSP to enforcing mode, then keep monitoring reports after each release.

Test on staging first, and check important flows such as login, checkout, payment redirects and contact forms after every change.

Macbook pro on black table

Where to Set Headers

You can set security headers in several places: your web server configuration, a reverse proxy, a CDN, your application framework or your hosting platform's settings. Choose one main place, so headers are not duplicated or overwritten inconsistently. Many frameworks have middleware or packages that make headers easier to manage in code, and some CDNs let you add headers without touching the server.

Document what you set and why. When a new marketing script or widget is requested later, the team will know the CSP needs updating, rather than discovering it when something breaks in production.

Checking Your Results

After deployment, check the headers with your browser's developer tools by inspecting the network response for a page. Free online header-scanning tools can also give a quick summary and point out missing headers, though treat their scores as guidance rather than a goal in themselves. A perfect score on a scanner matters less than a policy that protects your real users without breaking the site.

FAQ

Will security headers slow down my site?

No meaningful impact. Headers are small text instructions sent with responses. A strict CSP can even encourage you to remove unnecessary third-party scripts, which may make pages faster.

Is HSTS risky to enable?

It can be if parts of your site do not support HTTPS, because browsers will refuse insecure connections. Confirm HTTPS works everywhere and begin with a short max-age before increasing it.

Do I still need secure code if I have CSP?

Yes. CSP is a safety net, not a replacement. You still need input validation, output escaping, secure authentication and regular updates.

Security headers are one of the best value improvements a small web team can make. Start with the simple ones, roll out CSP carefully in report-only mode and keep the configuration documented, and your users get an extra layer of protection with very little ongoing cost.