Since the Edward Snowden fiasco, seems like security has been the latest buzz world around the water cooler. From the FBI accessing your webcam, NSA spying on virtual worlds, law enforcement spying on calls, to hackers hijacking commercial drones—doesn’t seem anybody is safe from the prying eyes of Big Brother.
As a web developer, I’m always on the lookout how to make my sites more secure. Recently, I was tasked with implementing a Content Security Policy. I had heard of CSP‘s before, but never really dug deep into them. After doing a little research, I’ve found that their an excellent way to help protect your site from malicious attackers and shady scripts. If you’re not using a Content Security Policy on your site, you should be.
- What is a Content Security Policy?
- Adding a Content Security Policy
- Content Security Policy Examples
- Testing Your Policy
- CSP Directive Reference
- CSP Source List Reference
Plug-in-Play Content Security Policy Options
What is a Content Security Policy?
A Content Security Policy is an HTTP response header that helps you reduce XSS risks on modern browsers by declaring what dynamic resources are allowed to load via a HTTP Header.
A CSP adds an extra layer of security that helps to detect and mitigate certain types of attacks, like Cross-site scripting (XSS) and data injection attacks. These attacks are used for everything from data theft to site defacement or distribution of malware. For the laymans, a CSP basically says, ‘Yes, it’s safe to load this file from an external website’, or ‘No, don’t load this file’.
Content Security Policy Browser Support
CSP is designed to be fully backward compatible; browsers that don’t support it sill work with servers that implement it, and vice-versa. If one is implemented and the browser doesn’t support it, it will simply ignore it. Instead, it will default to the standard same-origin policy for web content.
For more browsers and version support, take a look at caniuse.com/contentsecuritypolicy.
Adding a Content Security Policy
Enabling a CSP is as easy as configuring your web server to return the
Content-Security-Policy HTTP header (or browser specific header like Firefox 23 and below's
). You'll need to decide what policies you want to enforce, and then configure them using the CSP header to establish the policy.
Defining Your Policy
You can use the
Content-Security-Policy HTTP header to define your policy, where 'policy' is the directive:
CSPs are made up of one or more directives, multiple directives are separated with a semi-colin
;. Your policy should include a
default-src policy directive, which is a fallback for any resource type that you don't explicitly establish.
Content Security Policy Examples
Here's some common scenarios that arise when writing your security policy:
A web site administrator wants all content to come from the site's own domain, excluding even subdomains.
Content-Security-Policy: default-src 'self'
A web site administrator wants to allow content from a trusted domain and all its subdomains.
Content-Security-Policy: default-src 'self' *.mydomain.com
A web site administrator wants to allow users of a web application to include images from any domain in their custom content, but to restrict audio or video media to come only from trusted providers, and all scripts only to a specific server that hosts trusted code.
Content-Security-Policy: default-src 'self'; img-src *; media-src media1.com media2.com; script-src userscripts.example.com
Here, by default, content is only permitted from the document's original host, with the following exceptions:
- Images may loaded from anywhere (note the "*" wildcard).
- Media is only allowed from media1.com and media2.com (and not from subdomains of those sites).
- Executable script is only allowed from userscripts.example.com.
An administrator for an online banking site wants to ensure that all its content is loaded using SSL, in order to prevent attackers from eavesdropping on requests.
Content-Security-Policy: default-src https://onlinebanking.jumbobank.com
Content-Security-Policy: default-src 'self' *.mailsite.com; img-src *
Note that this example doesn't specify a
script-src; with the example CSP, this site uses the setting specified by the
default-src directive, which means that scripts can be loaded only from the originating server.
Testing Your Policy
To ease deployment, CSP can be deployed in "report-only" mode. The policy is not enforced, but any violations are reported to a provided URI. Additionally, a report-only header can be used to test a future revision to a policy without actually deploying it.
You can use the
Content-Security-Policy-Report-Only HTTP header to specify your policy, like this:
If both a
Content-Security-Policy-Report-Only header and a
Content-Security-Policy header are present in the same response, both policies are honored. The policy specified in
Content-Security-Policy headers is enforced while the
Content-Security-Policy-Report-Only policy generates reports but is not enforced.
The UserCSP Addon also helps test and develop Content Security Policies for a site.
CSP Directive Reference
||Defines valid sources of stylesheets.|
||Defines valid sources of images.|
||Defines valid sources of fonts.|
||Defines valid sources of plugins, eg
||Defines valid sources of audio and video, eg HTML5
||Defines valid sources for loading frames.|
||Enables a sandbox for the requested resource similar to the
||Instructs the browser to POST a reports of policy failures to this URI. You can also append
CSP Source List Reference
All of the directives that end with
-src support similar values known as a source list. Multiple source list values can be space seperated with the exception of
none which should be the only value.
||Wildcard, allows anything.|
||Prevents loading resources from any source.|
||Allows loading resources from the same origin (same scheme, host and port).|
||Allows loading resources via the data scheme (eg Base64 encoded images).|
||Allows loading resources from the specified domain name.|
||Allows loading resources from the any subdomain under
||Allows loading resources only over HTTPS matching the given domain.|
||Allows loading resources only over HTTPS on any domain.|
||Allows use of inline source elements such as style attribute, onclick, or script tag bodies (depends on the context of the source it is applied to)|