← Back to Apache Course | Chapter 4: Security | Lesson 4 of 4

Security Headers

Security headers are extra instructions Apache adds to every response, telling the browser to enforce protections -- like refusing to load the page in a frame, or always using HTTPS -- that the browser wouldn't apply on its own by default.

Why Headers, Not Just Code

Some protections are best enforced by the browser itself, and headers are how a server tells the browser to turn them on. Setting them centrally in Apache (rather than in every individual page's application code) guarantees they apply to every response from the site, including static files and error pages the application never touches.

The Essential Headers

Strict-Transport-Security (HSTS) tells the browser to only ever connect over HTTPS for a set period, even if a link points to http://. X-Content-Type-Options: nosniff stops the browser guessing a file's type differently from what the server declared. X-Frame-Options: SAMEORIGIN (or the newer Content-Security-Policy: frame-ancestors) prevents the page being embedded in another site's <iframe>, a common clickjacking defense.

Content-Security-Policy

Content-Security-Policy (CSP) is the most powerful and most complex of these headers -- it lets you declare exactly which sources scripts, styles, images, and other resources are allowed to load from, which meaningfully limits the damage a cross-site scripting (XSS) vulnerability can do. It also takes real effort to configure correctly, since an overly strict policy can break legitimate parts of a site.

Setting Them with mod_headers

All of these are set the same way, using Header always set (from the mod_headers lesson) so they apply to error responses too, typically in the main VirtualHost or a global config file so every site on the server gets them consistently.

Note: Test your headers with a tool like securityheaders.com or curl -I against the live site after deploying -- it's easy to have a typo in a directive that silently means the header never actually gets sent.

Example: A common security header baseline

apacheconf
<IfModule mod_headers.c>
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
    Header always set X-Content-Type-Options "nosniff"
    Header always set X-Frame-Options "SAMEORIGIN"
    Header always set Content-Security-Policy "default-src 'self'"
</IfModule>
{# Flagged by hand after confirming a runner can't handle this example (a shell command / go.mod file stored as a TopicExample, a language feature the configured runner version doesn't support, or output that blows a runner's sandbox limit) -- see TopicExample.norun. Never render the run button for these, regardless of language, since it would just fail at execute_code (or worse, hang the Judge0 queue on a submission that can never finish cleanly). #}

⚠️ This example can't run in the browser editor. Try it in your own local environment instead.

{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Setting security headers with Header set instead of Header always set, so they're missing on exactly the error responses where an attacker is most likely probing.
  2. Writing an overly strict Content-Security-Policy without testing it, breaking legitimate scripts/styles/fonts the site actually needs to load.
  3. Adding HSTS with a very long max-age before confirming HTTPS is fully working everywhere -- browsers will refuse to fall back to HTTP for that duration even if something breaks.
Chapter Summary
  • Basic Auth, IP-based access rules, and SSL/TLS each add a layer of access control -- from simple password prompts, to restricting by network location, to encrypting the connection itself with a real, auto-renewing certificate.
  • Security headers (HSTS, X-Content-Type-Options, X-Frame-Options, Content-Security-Policy), set centrally with Header always set, tell the browser to enforce protections on every response, including error pages.
🔒

Chapter Quiz — Complete all 4 topics to unlock

0/4 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.