Security Headers — The Browser's Perspective
The earlier "Securing Your Web Server" course covered these same headers from the server-configuration side — what to put in your Apache config. This chapter covers the same headers from the other end: what the browser actually does once it receives them, and why each one closes a specific, real attack rather than being generic best-practice advice.
Content-Security-Policy (CSP) — Restricting What a Page Can Load and Run
CSP tells the browser exactly which sources are allowed to provide scripts, styles, images, fonts, and other resources for a page — anything not explicitly allowed is simply blocked from loading or executing, no matter what HTML or JavaScript tries to request it.
| Directive | Controls |
|---|---|
| default-src | Fallback for any resource type not given its own directive |
| script-src | Where JavaScript is allowed to load from — the most security-critical directive |
| style-src | Where CSS is allowed to load from |
| img-src | Where images are allowed to load from |
| connect-src | Which origins fetch/XMLHttpRequest/WebSocket can connect to — directly relevant to Chapter 5's CORS coverage |
| frame-ancestors | Which sites are allowed to embed this page in an iframe — the modern replacement for X-Frame-Options, covered below |
'self' means "only this exact origin" (Chapter 5's definition of origin applies directly here). A strict CSP is one of the most effective defences against cross-site scripting (XSS) — even if an attacker manages to inject a <script> tag pointing at their own domain, a correctly configured script-src simply refuses to execute it.
Content-Security-Policy-Report-Only applies the same policy but only logs violations to the console (and optionally a reporting endpoint) without actually blocking anything — the standard way to test a new policy against real traffic before switching it to enforcing mode.
HSTS — Forcing HTTPS for Every Future Visit
Once a browser receives this header from a site, it remembers (for the given max-age, here one year) to never attempt an HTTP connection to that domain again — even if a user explicitly types http:// or clicks an old http link, the browser silently rewrites it to https before ever sending a request.
includeSubDomains applies HSTS to every subdomain too — meaning every subdomain must have valid HTTPS working, or they become entirely unreachable. preload submits the domain to a hardcoded list baked into browsers themselves, applying HSTS from a user's very first visit ever — genuinely difficult to reverse once submitted. Both are worth using deliberately, not by default, on a domain you're fully confident will keep working HTTPS indefinitely.
X-Frame-Options and frame-ancestors — Controlling Embedding
// Modern equivalent, more flexible, part of CSP:
Content-Security-Policy: frame-ancestors 'self';
These headers control whether another site can embed your page inside an <iframe> — without this restriction, an attacker can layer invisible iframes of your real site under deceptive buttons on their own page, tricking a logged-in user into clicking something on your site without realising it (a technique called clickjacking).
Checking What's Actually Configured
Browser DevTools → Network tab → click any request → Response Headers shows exactly which of these headers a site is actually sending — the fastest way to verify a server configuration change actually took effect, without guessing.
Chapter 6 Quick Reference
- CSP — whitelists allowed sources for scripts/styles/images/connections; the main defence against XSS at the browser level
- Content-Security-Policy-Report-Only — test a policy's violations without enforcing it yet
- HSTS — forces HTTPS for all future visits to a domain, closing the SSL-stripping window on a user's first connection
- includeSubDomains / preload — powerful but hard-to-reverse HSTS extensions; use deliberately
- X-Frame-Options / frame-ancestors — controls iframe embedding, the main defence against clickjacking
- Check headers via DevTools Network tab — Response Headers on any request
- Next chapter: session & auth tokens — cookies vs JWT vs server sessions, and where to safely store what