10.7 Security Headers

Security headers provide an additional layer of protection by instructing browsers how to handle various security-related behaviors. These headers help prevent common attacks like XSS, clickjacking, and content type sniffing while enforcing secure communication practices.

Implementing security headers correctly requires understanding both their protective benefits and potential compatibility impacts. Headers should be tested thoroughly to ensure they don’t break legitimate functionality while providing meaningful security improvements.

10.7.1 Content Security Policy (CSP)

Content Security Policy prevents XSS attacks by controlling which resources the browser is allowed to load. A well-configured CSP policy dramatically reduces the risk of malicious script execution while requiring careful consideration of legitimate third-party integrations.

For WordPress sites, CSP implementation must account for the platform’s dynamic nature and common plugin behaviors. Many WordPress plugins and themes inject inline scripts or load external resources that require specific CSP permissions.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
// WordPress CSP implementation
function add_security_headers() {
    if (!is_admin()) {
        $csp_policy = "default-src 'self'; " .
                     "script-src 'self' 'unsafe-inline' https://www.google-analytics.com https://www.googletagmanager.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://www.google-analytics.com";
        
        header("Content-Security-Policy: " . $csp_policy);
    }
}
add_action('send_headers', 'add_security_headers');

Laravel applications benefit from middleware-based header implementation, providing consistent application across all routes while allowing route-specific customizations when needed.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
// Laravel security headers middleware
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class SecurityHeaders {
    public function handle(Request $request, Closure $next) {
        $response = $next($request);
        
        // Content Security Policy
        $csp = "default-src 'self'; " .
               "script-src 'self' 'unsafe-eval'; " .
               "style-src 'self' 'unsafe-inline'; " .
               "img-src 'self' data: https:; " .
               "font-src 'self'";
               
        $response->headers->set('Content-Security-Policy', $csp);
        
        return $response;
    }
}

10.7.2 Frame Protection and Content Type Security

X-Frame-Options prevents clickjacking attacks by controlling whether pages can be embedded in frames or iframes. Most sites should deny framing entirely unless specific functionality requires iframe embedding from trusted sources.

X-Content-Type-Options prevents browsers from MIME-sniffing responses, forcing them to respect the declared content type. This header prevents attacks that exploit browser content type guessing behaviors.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
// Essential security headers for both platforms
function set_essential_security_headers() {
    // Prevent clickjacking
    header('X-Frame-Options: DENY');
    
    // Prevent MIME type sniffing
    header('X-Content-Type-Options: nosniff');
    
    // XSS protection (legacy support)
    header('X-XSS-Protection: 1; mode=block');
    
    // Referrer policy
    header('Referrer-Policy: strict-origin-when-cross-origin');
}

10.7.3 HTTPS Enforcement

Strict-Transport-Security (HSTS) headers enforce HTTPS connections for all future requests to the domain. This prevents protocol downgrade attacks and ensures that all communication remains encrypted after the initial secure connection.

HSTS implementation should include appropriate max-age values and consideration for subdomain inclusion. The includeSubDomains directive ensures that HTTPS enforcement applies to all subdomains, providing comprehensive protection.

1
2
3
4
5
6
<?php
// HSTS implementation with careful configuration
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') {
    // 1 year max-age with subdomain inclusion
    header('Strict-Transport-Security: max-age=31536000; includeSubDomains; preload');
}

10.7.4 Permissions Policy

The Permissions Policy header (formerly Feature Policy) controls which browser features and APIs the page can access. This header helps prevent unauthorized access to sensitive browser capabilities like camera, microphone, or geolocation.

1
2
3
4
5
6
7
8
9
10
11
<?php
// Permissions policy for typical business websites
$permissions_policy = 'geolocation=(), ' .
                     'microphone=(), ' .
                     'camera=(), ' .
                     'magnetometer=(), ' .
                     'gyroscope=(), ' .
                     'fullscreen=(self), ' .
                     'payment=()';

header('Permissions-Policy: ' . $permissions_policy);

10.7.5 Server-Level Implementation

While application-level headers work well, server-level implementation through web server configuration provides better performance and ensures headers are applied even when PHP doesn’t execute properly. Crowd Favorite works with our managed hosting providers so they are able to set these at a server level.

Apache .htaccess example

Header always set X-Frame-Options "DENY" Header always set X-Content-Type-Options "nosniff" Header always set X-XSS-Protection "1; mode=block" Header always set Referrer-Policy "strict-origin-when-cross-origin" Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"

Nginx configuration example

add_header X-Frame-Options “DENY” always; add_header X-Content-Type-Options “nosniff” always; add_header X-XSS-Protection “1; mode=block” always; add_header Referrer-Policy “strict-origin-when-cross-origin” always; add_header Strict-Transport-Security “max-age=31536000; includeSubDomains; preload” always;

10.7.6 Testing and Monitoring

Security headers should be tested thoroughly using tools like Mozilla Observatory, Security Headers scanner, or browser developer tools. These tools identify missing headers, configuration issues, and potential compatibility problems.

Regular monitoring ensures that security headers remain properly configured after deployments, server changes, or content updates. Automated testing can catch header regressions before they affect production security posture.

Implementation should be gradual, starting with report-only modes for CSP and monitoring for any breakage before enforcing stricter policies. This approach allows identification and resolution of compatibility issues without impacting user experience.


Copyright © 2025 Crowd Favorite. All rights reserved.

This site uses Just the Docs, a documentation theme for Jekyll.