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>