Antomor logo

Antomor's personal website.

Where ideas become words (maybe)

Security Headers on Static Websites

Security implication on hosting a static website on GitHub Pages

antomor

3-Minute Read

A key in a human hand

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 in a static website hosted on GitHub Pages. With this solution, I have been able to cut the cost on any host solution, since that, being a dev, I am quite comfortable in writing in a text editor. But soon some problem arises.

I discovered the impossibility to harden the server to customize the response headers. Why should someone customize the response headers? The response to question is:

“When she/he encounters securityheaders.com and she/he get an F”.

O.M.G.

I believe that many people do not apply the required security constraints due to the barriers they encounter to understand the reason behind. On the contrary, securityheaders.com made a very good job to let people understand what is wrong with the security headers, and why it is necessary to change them accordingly.

Why

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)

    • Content-Security-Policy usage instructs the browser about the content will be rendered in a page
    • Along with 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 if it is allowed rendering content in a frame.
  • Tab nabbing

  • and many more.

For a much detailed description about the risks associated with HTML5 page, please have a look at OWASP HTML5 Security Cheat Sheet.

How

You are here

So, back to this blog, how it is possible to reach an A+ report, running a static website on GitHub Pages? No, you don’t need to pay something to improve your website 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.

Here below 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 its post, where he exactly describes what each header is used for. I strongly recommend to have a look at rest of his blog for a detailed description of many security headers.

Resources

comments powered by Disqus

Recent Posts

Categories

About

Software Engineer passionate about Security and Privacy. Nature and animals lover. Sports (running, yoga, boxing) practitioner.