mod_headers
mod_headers lets you add, change, or remove HTTP response and request headers from the Apache config -- used constantly for security headers, caching hints, and CORS.Enabling It
On Ubuntu/Debian: sudo a2enmod headers then reload. On RHEL-family systems it's typically compiled in and just needs LoadModule headers_module modules/mod_headers.so uncommented.
The Header Directive
Header set Name "value" sets a response header, overwriting any existing one with that name. Header add appends a new header without removing an existing one of the same name. Header unset and Header always unset remove a header entirely -- useful for stripping information like Server or X-Powered-By that reveals server internals.
Conditional Headers
Header can take a condition, most commonly Header always set ..., where always makes sure the header is set even on error responses (4xx/5xx), not just successful ones -- important for security headers, which should apply to every response, not only the happy path.
Security and Caching Use Cases
The most common real-world use of mod_headers is adding security headers (covered in depth in the Security Headers lesson) like X-Content-Type-Options and Strict-Transport-Security, plus caching headers like Cache-Control on static asset directories to tell browsers how long to keep a file before re-requesting it.
Example: Setting security and caching headers
<IfModule mod_headers.c>
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header unset Server
</IfModule>
<FilesMatch "\.(css|js|jpg|png)$">
Header set Cache-Control "max-age=604800, public"
</FilesMatch>
{# 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). #}
- Using
Header setwithoutalwaysfor a security header, so it's missing exactly on the error responses (like a blocked request) where it matters most. - Forgetting
mod_headersneeds to be enabled separately -- writingHeaderdirectives that Apache doesn't recognize at all until the module is on. - Setting conflicting Cache-Control headers in both the application and in Apache's config, leaving it unclear which one actually wins for a given response.
Chapter Quiz — Complete all 5 topics to unlock
0/5 topics done
Complete these topics first: