In Depth: Content Security Policy
[InDepth#7] CSPs are an incredibly powerful security feature built into the browser.
Greetings Everyone! Sorry this one is a few days late1, COVID managed to rear it’s ugly head and knock me around for a few days. We’re all recovering now, although stuck in isolation for the next week.
This month we’re going to be diving into Content Security Policy (CSP), which is a topic I’ve wanted to cover since I started Laravel Security in Depth. (I’m not sure why I waited so long!) CSPs are an interesting beast: they sound incredibly complicated and tricky to set up on existing sites, but they also include what you need to make setting them up pretty easy.
I ended up covering so much in here that this is my first email to smash past the Gmail email truncation length. I’d recommend clicking on the title 👆 and reading it in your browser.
Just a reminder: I can hack your site to help you improve your security, check out my Laravel Security Audits and Penetration tests.
Content Security Policy
A Content Security Policy (CSP) is an incredibly powerful web application security feature built into modern web browsers. It adds an extra layer of security by blocking unexpected content from executing, preventing Cross-Site Scripting and other injection attacks from affecting your site.
You define a Content Security Policy on your site through the a response header or a meta tag. The browser checks for a CSP before rendering the page, and if it finds one, it will follow the policy and prevent any unexpected resources from loading.
A CSP defines a list of directives relating to specific content types (i.e. scripts, styles, images, fonts, etc), and the resources from where these content types can be loaded. This allows them to be both incredibly specific and incredibly flexible, depending on what you need to cover your site. For example, you can use a CSP to only allow Javascript when loaded from an external file hosted on the same domain, while also allowing inline styles and fonts loaded from a third-party domain.
HTTP Header:
Content-Security-Policy: _policy_
HTML Meta Element:
<meta http-equiv="Content-Security-Policy" content="_policy_">
CSPs may sound quite daunting and complicated to set up (and like a great way to break your site!), but they are a lot simpler than they sound. Plus they include some features that make setting them up quite simple!
Writing a Basic CSP
Let’s get started with a simple example, to give you an overview of what a CSP is and how it works.
I’ll use a local copy of our demo site as an example, adding a basic CSP header. When I tell it to block everything through a CSP, you can see the page looks rather broken:
This is the CSP header I added to the page:
Content-Security-Policy: default-src 'none' ; form-action 'none' ; frame-ancestors 'none'
And the error message in the console is:
Refused to load the stylesheet 'https://larasec.valorin.dev/css/app.css?id=...' because it violates the following Content Security Policy directive: "default-src 'none'". Note that 'style-src-elem' was not explicitly set, so 'default-src' is used as a fallback.
There are a few things going on here, so let’s bisect it.
Keep reading with a 7-day free trial
Subscribe to Securing Laravel to keep reading this post and get 7 days of free access to the full post archives.