How to Protect HTTP Headers on Apache

Last Updated on 9 de Janeiro, 2021 by Vítor Fernandes

HTTP headers allow the client and the server to pass additional information with the request or the response. A request header consists of its case-insensitive name followed by a colon ‘:’, then by its value (without line breaks). Leading white space before the value is ignored.

Our HTTP headers are already safe. Check it out!

For further clarification see some examples on Permissions-Policy and Policy directives oficial webpage. Check you webpage settings and ajust as much as possible!

1 – Setting headers directive with “always” option

Because without “always” the directives will only go out on successful responses.

Header always set Connection Keep-Alive
Header always set Keep-Alive "timeout=5, max=1000"
Header always set X-Cache HIT
Header always set Alt-Svc h2=":443"
Header always set Content-Language pt-PT
Header always set Accept "text/html, application/xhtml+xml, application/xml;q=0.9, image/webp, */*;q=0.8"
Header always set Cache-Control "no-cache, no-store, must-revalidate"
Header always set Strict-Transport-Security "max-age=31536000; preload"
Header always set Permissions-Policy "autoplay=(self), camera=()"
Header always set Referrer-Policy strict-origin-when-cross-origin
Header always set Content-Security-Policy upgrade-insecure-requests
Header always set X-XSS-Protection "1; mode=block"
Header always set X-Content-Type-Options nosniff
Header always set X-Frame-Options SAMEORIGIN

2 – Disable unnecessary options

Header unset X-Powered-By
Header unset X-DNS-Prefetch-Control
Header unset Last-Modified
Header unset Expires
Header unset Link
Header unset Server
Header unset Via
Header unset P3P
Header unset Public-Key-Pins
Header unset Public-Key-Pins-Report-Only
Header unset X-AspNet-Version
Header unset X-AspNetMvc-version
Header unset X-Runtime
Header unset X-Version
Header unset X-UA-Compatible

Sometimes, this configuration is not possible because of the limitation that user have with is hosting provider. So, in this case you could do within Cloudflare platform!

Cloudflare Workers configuration

Go to workers, manage workers, create a worker then add the following code

let securityHeaders = {
	"Content-Security-Policy" : "upgrade-insecure-requests",
	"Strict-Transport-Security" : "max-age=31536000; preload",
	"X-Xss-Protection" : "1; mode=block",
	"X-Frame-Options" : "SAMEORIGIN",
	"X-Content-Type-Options" : "nosniff",
	"Referrer-Policy" : "strict-origin-when-cross-origin",
	"Permissions-Policy" : "autoplay=(self), camera=()",

let sanitiseHeaders = {
	"Server" : "headers override",

let removeHeaders = [

addEventListener('fetch', event => {

async function addHeaders(req) {
	let response = await fetch(req)
	let newHdrs = new Headers(response.headers)

	if (newHdrs.has("Content-Type") && !newHdrs.get("Content-Type").includes("text/html")) {
        return new Response(response.body , {
            status: response.status,
            statusText: response.statusText,
            headers: newHdrs

	Object.keys(securityHeaders).map(function(name, index) {
		newHdrs.set(name, securityHeaders[name]);

	Object.keys(sanitiseHeaders).map(function(name, index) {
		newHdrs.set(name, sanitiseHeaders[name]);


	return new Response(response.body , {
		status: response.status,
		statusText: response.statusText,
		headers: newHdrs