Content security policies (CSPs) have been around for years and are a great way to provide blanket protection from various web page vulnerabilities. CSPs are typically delivered to a browser using a response header from the web server such as Content-Security-Policy. This works great and provides the broadest range of support for CSP features.
But what if we have no control over the HTTP responses from the web server? When a site is hosted on GitHub pages, there is no access to the web server, so we can’t return our own response headers. The following solution will work for any hosting environment where we can’t modify response headers.
How to Implement
Enter the CSP <meta> tag.
When modifying response headers is not an option, we have an alternative method for adding a CSP: using a meta tag.
This meta tag will go in the <head> element of the page, before our content, links, and scripts. The ‘http-equiv’ value is a constant, and the ‘content’ field is the policy we would like to enforce. The format for the CSP definition is the same as what would be sent in the response header. To read more about how to build a content security policy, go here.
We can also specify multiple CSP meta tags to accomplish specific needs, just like using the header-based approach.
Here is a more complete example of what the head of our HTML document might look like.
There are a few issues we may run in to when implementing a CSP using the meta tag.
Including content before the CSP meta tag
If any content links appear before the CSP meta tag, the CSP will not apply to them. For example, the following sample will load the CSS file ‘stealyourdata.css’, even though our CSP should be blocking it.
Using CSP directives not supported in meta tags
There is a short list of CSP directives that will not work when delivered using a meta tag. We will want to make sure our site does not rely on these directives to operate. The unsupported directives are
While delivering content security policies using a response header is the preferred method, we can still meet our needs in environments where we cannot control response headers. If you are interested in learning more about content security policies, see the official docs.