Content security policy for font awesome on Netlify

Tue, Jul 28, 2020 3-minute read

When setting up this very web page, everything initially went smoothly, up until I ran into the issue of ‘Content Security Policy’ (CSP). This tickled my memory, but my web dev skills being a bit rusty it took some hours of screening the internet to understand how:

  1. What the Content Security Policy is
  2. How to format content security headers for deployment on Netlify
  3. Setting up the Content Security Policy to permit external fonts

Disclaimer: I am no web development expert, and despite working out OK, it might not be the optimal way to do things. If you spot major issues, please let me know!

The error

The errors I encountered appeared in the browser console, looking something like the following:

Content Security Policy: The page’s settings blocked the loading of a resource at inline (“default-src”). onloadwff.js:71:798525
Content Security Policy: The page’s settings blocked the loading of a resource at https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css (“default-src”).

These are two separate errors. One is related to how the scripts are loaded (inline), and one due to the external scripts of the target type (in this error - CSS) was loaded.

What the Content Security Policy is

This is defined in much detail by Mozilla with some very helpful examples. In brief - It is a security functionality used by the browser to control what types of contents are allowed to run on what platform. For instance - you can permit only scripts to be sourced from the server at hand. Or, you can allow external CSS-files from specific given sites.

How to format content security headers for deployment on Netlify

There are multiple possible methods for deployment as specified by Netlify. The method I used was using a netlify.toml configuration file placed in the base folder for the web page repository. This file is loaded when deployed by Netlify.

Here, the first go at content security policy is shown below. This allows everything served from the current site to be loaded, but does not permit anything from external sites.

[[headers]]
  for = "/*"
    [headers.values]
    Content-Security-Policy = "default-src 'self'"

When running this, everything loaded well with the exception of icons from Font Awesome, which was not loaded due to coming from an external site.

Setting up the Content Security Policy to permit external fonts

In order to allow reading of fonts from an external site I needed the following pieces of information.

The default-src used for the CSP is the default fallback for any type of script. Different sub-types can be redefined, updating their target site. For instance, to extend from where JavaScript files can be loaded, the script-src directive can be used. Note the quotes on the ‘self’, but no quotes on the URL. By redefining the ‘self’ the JS-files can be loaded both from the own site and the additional site.

[[headers]]
  for = "/*"
    [headers.values]
    Content-Security-Policy = "default-src 'self'; script-src 'self' https://stackpath.bootstrapcdn.com"

Finally, to allow loading of the Font Awesome, I needed to include both JavaScript-files (script-src), CSS files (style-src) and font sources (font-src). Further, in this case (as this was how it was defined by the web page theme I used), the unsafe-inline directive needed to be used, as the scripts were imported using inline <script> elements or similar (described further here under ‘unsafe-line’).

[[headers]]
  for = "/*"
    [headers.values]
    Content-Security-Policy = "default-src 'self'; script-src 'self' 'unsafe-inline' https://stackpath.bootstrapcdn.com; style-src 'self' 'unsafe-inline' https://stackpath.bootstrapcdn.com; font-src 'self' 'unsafe-inline' https://stackpath.bootstrapcdn.com"

With this, things worked well!