How I made 1000's of websites more secure with one line of code

April 24, 20194 min read

Or at least a lot of them

Learning about a new security header

Last week, I attended the London Django meetup. Among a very interesting lineup of talks, there was a lighning presentation from Adam Johnson about security headers and how Django helps with them. If you don’t know what security headers are, I urge you to watch the talk, it’s a bit about Django but it applies about the web in general.

While I knew the ones that comes with Django and the very important Content-Security-Policy, I discovered the Referrer-Policy header, including the story of the Referer header mispelling from the early days of the web.

In the presentation, Adam mentioned a tool to check your site and educate about all the possible security headers: Scott Helme’s I was already following Scott on Twitter -I learned a great deal about CSP thanks to him- but although he probably mentioned this tool, I forgot about it.

Fixing my sites

After the presentation, I decided to check for a couple of my recent sites I built with Gatsby which I expected to be pretty well covered. After checking, they were pretty well covered, but to my surprise, the Referrer-Polocy wasn’t set.

I quickly found that this could be easily set via an option from gatsby-plugin-netlify. I started adding it and set it to the suggested value of 'same-origin', which seems pretty sensible:

module.exports = {
  plugins: [
      resolve: `gatsby-plugin-netlify`,
      options: {
        headers: {
          '/*': ['Referrer-Policy: same-origin'],

It all worked fine so I was going to add it to my other website, but then it struck me that maybe I can push this to all websites built with Gatsby by contributing upstream, & multiply my impact! A quick check for showed similar results as my own sites: security headers report before

Fixing 1000’s of website at once

So I went ahead and forked the repository on Github and quickly located where the Netlify plug-in is located in their monorepo architecture. Once in there, the plug-in codebase is actually pretty small so it was not hard to find the entry point and where to make the change, in their SECURITY_HEADERS constants:

export const SECURITY_HEADERS = {
     `X-Frame-Options: DENY`,
     `X-XSS-Protection: 1; mode=block`,
     `X-Content-Type-Options: nosniff`,
     `Referrer-Policy: same-origin`,

Ideally I wanted to write tests but couldn’t find any for the existing headers. Since the change was small, I decided to open a draft pull request, with the plan to fix potential test failures later, but there was none. I marked it as ready for review and at this point I was expecting to wait for a while.

The Gatsby community

Only a few hours later, a maintainer jumped in, approved my pull request with a extremely welcoming message and then merged it:

Pull request approved

After that, a bot invited me into their organisation on Github with a welcome message, and pointed at their store where I could order a free swag!

Gatsbot message

This an amazing contributor experience, I found this super welcoming and positive. Not every open source project can afford to give away some free swag, but a bit of automation around welcoming new contributors can go a long way in building a thriving community. I’ll surely consider contributing again.

An easy win to achieve that is via Probots (and maybe also Action soon). There is a welcome app that does something similar as the Gatbsy bot and which can be added to your project in a few minutes.


After this got merged, I wanted to see my change propagated to the site. I checked again and here it was: security headers report after

Next steps

It would be nice to set the CSP, but as Adam pointed in his talk, this is a big one to implement -especially on existing sites- and there is no simple default. Gatsby has an open issue to track some of the challenges around CSP.

I’m planning to add it to my websites and see how this goes, I’ll probably use gatsby-plugin-csp as it looks promising.