Essential Security Headers for Apache
Essential Security Headers for Apache
Implementing security headers in Apache requires enabling the headers module and carefully configuring each header. Start by ensuring the module is active:
sudo a2enmod headers
sudo systemctl restart apache2
Configure comprehensive security headers in your Apache virtual host or global configuration:
<IfModule mod_headers.c>
# Strict Transport Security - Enforce HTTPS
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
# X-Frame-Options - Prevent clickjacking
Header always set X-Frame-Options "SAMEORIGIN"
# X-Content-Type-Options - Prevent MIME type sniffing
Header always set X-Content-Type-Options "nosniff"
# X-XSS-Protection - Enable XSS filtering (legacy but still useful)
Header always set X-XSS-Protection "1; mode=block"
# Referrer-Policy - Control referrer information
Header always set Referrer-Policy "strict-origin-when-cross-origin"
# Content Security Policy - Comprehensive XSS and injection protection
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.example.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https:; connect-src 'self' https://api.example.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; upgrade-insecure-requests;"
# Permissions Policy (formerly Feature Policy)
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=(), usb=(), magnetometer=(), accelerometer=(), gyroscope=()"
# X-Permitted-Cross-Domain-Policies - Control cross-domain content handling
Header always set X-Permitted-Cross-Domain-Policies "none"
# Clear-Site-Data - Clear browsing data on logout
<Location /logout>
Header always set Clear-Site-Data '"cache", "cookies", "storage"'
</Location>
# Remove potentially dangerous headers
Header always unset X-Powered-By
Header always unset Server
# Cache-Control for security-sensitive content
<FilesMatch "\.(html|php)$">
Header set Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0"
Header set Pragma "no-cache"
Header set Expires "0"
</FilesMatch>
</IfModule>