When I started this blog, I evaluated many options:
- blogging platform vs static-generated website
- self-hosted vs hosted solutions
- costs
- and many more.
I ended up trying to build something very simple, consisting of a static website hosted on GitHub Pages. With this solution, I have been able to cut the cost of any hosting solution, since, being a dev, I am quite comfortable writing in a text editor. But soon some problems arose.
I discovered it was impossible to harden the server to customize the response headers. Why should someone customize the response headers? The response to that question is:
“When she/he encounters securityheaders.com and she/he gets an F”.

I believe that many people do not apply the required security constraints due to the barriers they encounter in understanding the reasoning behind them. On the contrary, securityheaders.com did a very good job of letting people understand what is wrong with their security headers, and why it is necessary to change them accordingly.
Why#

Although there is a misleading conception that static websites are intrinsically secure, web server misconfiguration represents one of the attack vectors shared among dynamic and static websites.
Web server misconfiguration can lead to well-known vulnerabilities such as:
Referrer leakage
- With the Referrer-Policy, it is possible to instruct the browser not to send the referrer header along with requests.
XSS (Cross-site scripting)
- Using Content-Security-Policy instructs the browser about what content will be rendered on a page
- Along with the CSP security header, it would be useful to set the X-XSS-Protection header to instruct old browsers not to render the page if an attack is detected.
Click-jacking
- The X-Frame-Options header can be used to instruct the browser whether it is allowed to render content in a frame.
Tab nabbing
- Along with other mechanisms that can be used to mitigate this attack, setting the Referrer-Policy header can also be useful.
and many more.
For a much more detailed description of the risks associated with HTML5 pages, please have a look at the OWASP HTML5 Security Cheat Sheet.
How#

So, back to this blog: how is it possible to reach an A+ report while running a static website on GitHub Pages? No, you don’t need to pay anything to improve your website’s security.
A free plan on Cloudflare is enough 😎.
We are going to customize the response headers by using the Cloudflare Workers service provided by the Cloudflare free tier.
Below is the script to be used. It can also be found on GitHub.
let securityHeaders = {
"Content-Security-Policy" : "upgrade-insecure-requests",
"Strict-Transport-Security" : "max-age=2592000",
"X-Xss-Protection" : "1; mode=block",
"X-Frame-Options" : "DENY",
"X-Content-Type-Options" : "nosniff",
"Referrer-Policy" : "strict-origin-when-cross-origin",
"Feature-Policy": "accelerometer 'none'; camera 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'; payment 'none'; usb 'none'"
}
let sanitiseHeaders = {
"Server" : "My New Server Header!!!",
}
let removeHeaders = [
"Public-Key-Pins",
"X-Powered-By",
"X-AspNet-Version",
]
addEventListener('fetch', event => {
event.respondWith(addHeaders(event.request))
})
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
})
}
let setHeaders = Object.assign({}, securityHeaders, sanitiseHeaders)
Object.keys(setHeaders).forEach(name => {
newHdrs.set(name, setHeaders[name]);
})
removeHeaders.forEach(name => {
newHdrs.delete(name)
})
return new Response(response.body , {
status: response.status,
statusText: response.statusText,
headers: newHdrs
})
}I took the script from the creator of securityheaders.com, from his post, where he describes exactly what each header is used for. I strongly recommend having a look at the rest of his blog for a detailed description of many security headers.
