DEV Community

Roel Hogervorst
Roel Hogervorst

Posted on • Originally published at on

Setting up CSP on your hugo (+netlify) site

I recently got a compliment about having a content security policy (CSP) on my blog.

But I’m not special, you can have one too!

In this post I will show you how I created this policy and how you can too.I’m using the service which automates a lot the work.This is specific for building a hugo site using netlify. I am absolutely no expert and so this is mostly a description of what I did.

In short:

  • put a _headers file in the ‘static/’ folder
  • fill this file with basic security headers
  • set up a report-uri or (a source to which reports should go)
  • set the content-security policy (CSP) to report-only
  • wait
  • learn from the reports what should be allowed and what not
  • set the CSP from what you learned
  • set the CSP to blocking mode

Basic setup

  • Everything in the ‘/static’ folder in your hugo project is placed at root of the website.
  • If you have a file called _headers in your root netlify will pick thatup and use it as header information.

So if you place a _headers file in the ‘/static’ folder of your blog foldernetlify will process that and create response headers for you.

My setup

I use github (but you can self host, use gitlab or anything else) to build myblog. Whenever a new blogpost is uploaded github tells netlify and netlify (runshugo and) builds the website. You can also create a header file that is just abunch of rules that netlify will obey for your website. As explained here.

This is your CSP telling the website not anything can be loaded

What are headers?

When your browser communicates with a server they exchange packages, there is contentin the packages and there is some meta-information. Your browser tells the serverwhat kind of browser it is and what kind of information it wants to receive. Andthe server tells the browser what kind of server it is, and what is allowed andnot allowed. We call these rules headers. Just to make it more confusing: themetadata on top of a website is called the head.I know… There was little user research in those early dark days of the internet.

So what is in my headers?

See my ‘_headers’ file here, but don’t blindly copy it! I have a much betterway for you to build this information later on.

Top of the file:

  X-Frame-Options: DENY
  X-XSS-Protection: 1; mode=block
  X-Content-Type-Options: nosniff

What does the header file say:

  • /* for all pages on
  • X-frame options Disable iframes from other places.
  • ‘X-XSS-Protection: Cross site scripting protection: does not let the page load when a cross site scripting is detected
  • X-content-type-options: Don’t really know what it does, but it is recommended.

But then follows the CSP:

This stops XSS

default-src 'self'

This CSP tells what default-src can deliver content, where code, images, css and fonts can be loaded from.

I did not manually type out all of the domains I use on my website. I don’t havethe time.

I use a service called . You can start with following a wizard
and adding some basic CSP thingies to your headers. You set your CSP to report-only
(so not blocking anything, but only reporting). This makes all browsers who visit
your site report all the sources to report-uri.

For an alternative use Bob Rudis (@hrbrmstr )’s post on setting up a report-uriyourself on AWS s3.

I didn’t know about it, and report-uri works too, so choose what you want.

Maybe I went a bit overboard on the stop images

All the reports are coming in to the report-uri website now and you can check later (dependingon the traffic) what sources are reported. On the report-uri website you can say whichsources should be allowed and which should be blocked and in the end you end upwith a CSP that you can copy into the headers file.

So tl;dr

  • put in _headers file in ‘static/’
  • fill with basic security headers
  • set up a report-uri (a source to which reports should go)
  • set the CSP to report-only
  • wait
  • learn from the reports what should be allowed and what not
  • set the CSP from what you learned
  • set the CSP to blocking mode

Image sources

Top comments (0)