Apache: How to get an A (or A+) rating on securityheaders.com

A commenter on my old post about configuring security headers on Nginx (and getting an A or A+ rating on securityheaders.io, now moved to securityheaders.com) asked for a version for Apache, so… here it is. It’s basically the same, just with the appropriate syntax changes:

Nginx setting Explanation
header always set Strict-Transport-Security “max-age=31536000; includeSubdomains; preload” Enforces HTTPS on the entire site. Don’t use if you still need to provide HTTP, of course.
header always set X-Content-Type-Options nosniff Prevents browsers from trying to “guess” MIME types and such, forcing them to use what the server tells them.
header always set X-Frame-Options SAMEORIGIN Stops your site from being included in iframes on other sites.
header always set X-Xss-Protection “1; mode=block” Activates cross-scripting (XSS) protection in browsers.
header always set Referrer-Policy “unsafe-url” Makes the site always send referrer information to other sites. NOTE: this is not the most secure setting, but it’s the one I prefer; see below.
header always set Content-Security-Policy “default-src https: data: ‘unsafe-inline’ ‘unsafe-eval'” Forces TLS (don’t use if you still need to provide HTTP); prevents mixed content warnings. NOTE: again, this is not the most secure setting; see below.

About the last two settings, I’ll copy from my old post:

I choose to send referring information to other sites for a simple reason: I like to see where my own visitors come from (I don’t sell, share or monetize that in any way, it’s just for curiosity’s sake), and I’m a firm believer in treating others as I want to be treated. If you don’t care about that, you may want to change this to “no-referrer-when-downgrade“, or “strict-origin“.

As for the Content Security Policy, anything more “secure” than the above prevents (or at least makes it a lot more headache-inducing) the use of inline scripts and/or external scripts, which would mean no external tools/scripts/content (or at least a lot of work in adding every external domain to a list of exceptions), and a lot of hacking on software such as WordPress (seriously: add the setting, but then remove the “unsafe-*” options and see what stops working…). You might use the most paranoid settings for an internally developed, mostly static site, but I fail to see the point. So, this and the paragraph above are the reasons for an A rating, instead of an A+.

Hope this was useful. 🙂