Paul Bradley • Solutions Architect & Software Developer


Published:

HTTP Security Headers a Caddy Web Server Configuration

midjourney ai - anthropomorphic shark gladiator

Caddyfile Configuration for Security Headers

I’ve been using Caddy as my web server for several years. It’s been rock solid and stable. Consider it if you’re looking for a modern web server. Don’t default to Apache or NGINX; consider the alternatives.

I’d not updated the configuration file for a long time, so I reviewed the HTTP headers that the server emits with each request today. In particular, I’ve focussed on the HTTP headers used to control security.

As such, I’ve added Cross-Origin-Opener-Policy, which provides a way for a document to isolate itself from cross-origin windows opened through window.open() without rel=“noopener” — this is useful, as it means I don’t have to add the rel tag to all links.

I’ve also added the Cross-Origin-Embedder-Policy header, which prevents documents and workers from loading cross-origin resources such as images, scripts and stylesheets.

My current Caddyfile configuration for HTTP headers:

header * {
    Access-Control-Allow-Origin "https://du89og34n262.cloudfront.net"
    Cache-Control "max-age=86400, must-revalidate"
    Content-Security-Policy "default-src 'self' blob: data: https://du89og34n262.cloudfront.net https://www.youtube-nocookie.com; font-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' blob: 'unsafe-inline' 'unsafe-eval' https://www.youtube-nocookie.com; connect-src 'self' https://du89og34n262.cloudfront.net;"
    Cross-Origin-Embedder-Policy "require-corp"
    Cross-Origin-Opener-Policy "same-origin-allow-popups"
    Cross-Origin-Resource-Policy "same-origin"
    Permissions-Policy "accelerometer=(self), ambient-light-sensor=(self), autoplay=(self), battery=(self), camera=(self), cross-origin-isolated=(self), display-capture=(self), document-domain=(self), encrypted-media=(self), execution-while-not-rendered=(self), execution-while-out-of-viewport=(self), fullscreen=(self), geolocation=(self), gyroscope=(self), keyboard-map=(self), magnetometer=(self), microphone=(self), midi=(self), navigation-override=(self), payment=(self), picture-in-picture=(self), publickey-credentials-get=(self), screen-wake-lock=(self), sync-xhr=(self), usb=(self), web-share=(self), xr-spatial-tracking=(self)"
    Server "paulbradley.dev"
    Strict-Transport-Security max-age=31536000;
    X-Content-Type-Options nosniff
    X-Frame-Options DENY
    X-XSS-Protection "1; mode=block"
}

Versions