Editorial: This page was last updated Oct 27th, 2022.
- What is a Content Security Policy (CSP)?
- Why do I need a CSP?
- How to set up a CSP
- Common CSP Directives
- Common Source Values for -src Directives
- Where to set the HTTP Response Header
- Content Security Policy Examples
- Now that I have a CSP, does that mean I am safe?
What is a Content Security Policy (CSP)?
Content Security Policy (CSP) is a policy that uses headers or meta elements to restrict or greenlight what content loads onto your website. It is a widely-supported security standard recommended to anyone who operates a website.
Why do I need a CSP?
Using a CSP adds a layer of protection to your website by stating rules of what is or isn’t allowed. These rules help to defend against content injections and cross-site-scripting (XSS) attacks, two of OWASP’s top 10 Web Application Security Risks.
XSS attacks happen when an attacker is able to compromise an unprotected website by injecting malicious code. When a user tries to interact with the site, the malicious script executes in the user’s browser, giving the attacker access to the victim’s interactions with the site, like login information etc.
How do I set up a CSP?
Follow along for a quick overview of Content Security Policies, how to write them, and how they get implemented.
Step 1 – Define your CSP
Make a list of policies or directives and source values that state which resources your site will allow or restrict.
Common CSP Directives
Here’s list of common CSP Directives and source values for you to mix and match.
|default-src||default-src ‘self’ cdn.example.com;|
|script-src||script-src ‘self’ js.example.com;|
|style-src||style-src ‘self’ css.example.com;|
|img-src||img-src ‘self’ img.example.com;|
Example default-src policy:
default-src 'self' cdn.example.com
Defines authorized sources for scripts.
Example script-src policy:
script-src ‘self’ js.example.com
Defines authorized sources for stylesheets (CSS).
Example style-src policy:
style-src ‘self’ css.example.com
Defines authorized sources for plugins. (ie. <object> or <embed>)
Example object-src policy:
Defines authorized sources for images, or link element related to an image type (ie. rel=”icon”)
Example img-src policy:
img-src ‘self’ img.example.com
Defines authorized sources for media elements. (ie. <video> or <audio>)
Example media-src policy:
Defines authorized sources for loading frames. (iframe or frame)
Example frame-src policy:
Defines authorized sources where fonts files can be loaded from.
Example font-src policy:
Policy applies to connections from a XMLHttpRequest (AJAX) or a WebSocket.
Example connect-src policy:
Instructs a browser to create a report of policy failures. If a piece of content is blocked, the browser will send a report of the information to this URI.
Alternatively, you can use Content-Security-Policy-Report-Only as the HTTP header name to receive the reports without blocking anything.
Example report-uri policy:
Allows you to add header for the Content Security Policy (CSP).
Example add_header policy:
add_header Content-Security-Policy “default-src ‘self’;”;
Common Source Values for -src Directives
Here is a list of common source values for -src directives.
|*||img-src *||Wildcard, allows any URL except data: blob: filesystem: schemes.|
|‘none’||object-src ‘none’||Prevents loading resources from any source.|
|‘self’||script-src ‘self’||Allows loading resources from the same origin (same scheme and domain name).|
|data:||img-src ‘self’ data:||Allows loading resources via the data scheme (eg Base64 encoded images).|
|domain.example.com||img-src domain.example.com||Allows loading resources from the specified domain name.|
|*.example.com||img-src *.example.com||Allows loading resources from any subdomain under example.com|
|https://cdn.com||img-src https://cdn.com||Allows loading resources only over HTTPS matching the given domain|
|https:||img-src https:||Allows loading resources only over HTTPS on any domain.|
|‘unsafe-inline’||script-src ‘unsafe-inline’||Allows use of inline source elements such as style attribute, onclick, or script tag
Content Security Policy Examples
Now let’s mix and match some common directives and source values. For your reference, we’ve provided examples below to address a few common scenarios.
Tip: When making a CSP, be sure to separate multiple directives with a semicolon.
SCENARIO 1 – PREVENT IFRAMES:
Prevent iFrames from loading on your site.
Content-Security Policy:script-src 'none'
SCENARIO 3 – RESTRICT CONTENT OTHER THAN IMAGES:
Allow images to load from any domain, but restrict other content from loading except that from your own website.
Content-Security-Policy: default-src 'self'; img-src *;
Tip: It is important to set the default-src to ‘self’ or ‘none’ (and explicitly list the allowed resources), otherwise it will default to allowing all.
Note that ‘self’ does not include any of your sub-domains.
SCENARIO 4 – ONLY ALLOW CONTENT FROM SAME ORIGIN:
Only allow content to load from the same origin, your website, and its subdomains.
Content-Security-Policy: default-src 'self' *.sucuri.net;
Note: Because the content that will be loaded from sucuri.net is not specifically mentioned in the CSP, default-src will allow all content in.
SCENARIO 5 – ONLY ALLOW MEDIA OR EXECUTABLE SCRIPTS FROM SAME ORIGIN:
Allow images to load from anywhere but only want to allow media or executable scripts that come from the same origin.
Content-Security-Policy: default-src 'self'; img-src *; media-src sucuri.net; script-src sucuri.net;
Tip: This is a kind of rule you would need if you had a CDN or a media sub-domain from where you serve all your media.
SCENARIO 6 – ONLY ALLOW IMAGES, SCRIPTS, FORM ACTIONS & CSS FROM SAME ORIGIN:
You want to allow images, scripts, form actions, and CSS from the same origin, but nothing else to load.
default-src 'none'; script-src 'self'; img-src 'self'; style-src 'self';base-uri 'self';form-action 'self'
Step 2 – Test your CSP before implementing it
Test out your CSP to make sure you didn’t forget to include any trusted domain origins your site needs.
- You can receive alerts of violations to your policy without blocking the content, by setting the HTTP Response header to Content-Security-Policy-Report-Only .
- You can also add the directive report-uri with a URL where you would like to see reports about CSP violations.
Where to set the HTTP Response Header
Most modifications to your HTTP Response header will happen in the configuration file.
- Find out what server your website is running on. You can also log into your cPanel and check under the Server Information interface to find out. This will show the server that hosts your account.
- Once you know your server, set your HTTP response header within the corresponding configuration file as detailed below. We have also linked additional resources for greater detail.
IIS (Internet Information Services)
- Open the IIS manager
Media source: docubrain.com
- On the left select the website that you want to set the HTTP Response Header for
- Select the HTTP Response Headers icon
- Select “add” and enter your name and value for the header
Media source: docubrain.com
Alternatively, if you don’t want to open the IIS manager you can add your policy to the web.config file. It will look something like this depending on the directives you chose:
<system.webServer> <httpProtocol> <customHeaders> <add name=”Content-Security-Policy” value=”default-src 'self'; img-src*” /> </customHeaders> </httpProtocol> </system.webServer>
More information at Modifying HTTP Response Headers.
If you have an Apache web server, you will define the CSP in the .htaccess file of your site, VirtualHost, or in httpd.conf.
Depending on the directives you chose, it will look something like this:
Header set Content-Security-Policy-Report-Only "default-src 'self'; img-src *"
The HTTP response header is modified through the corresponding config files within the server blocks. By adding an [add_header] directive, you set the response header.
In Nginx, it looks like this:
add_header Content-Security-Policy"default-src 'self'; img-src *"
More information here.
Now that you’ve tested out your CSP, it’s time to implement!
Step 3 – Implement your CSP
There are two ways to configure your system to start enforcing your CSP. The first option works on all browsers, but is less popular. The second option is the same way we tested our Content-Security-Policy-Report-Only, we set the HTTP Response Header.
- Meta Tags: If you do not have access to your web server’s configuration, you can use the HTML tag to enable your CSP inside the page’s HTML. Set the <meta> in the <head> so it begins working ASAP.
<head> <meta http-equiv=”Content-Security-Policy” content=”default-src ’self’; img-src *”> </head>
- CSP HTTP Response Header: This is the recommended way to implement a CSP by W3. Most browsers (except Internet Explorer and some older browser versions) support using a CSP HTTP Response header, but you can double check here at Can I Use.
Refer back to Set the HTTP Response Header for details for your specific web server, but this time you will use Content-Security-Policy without the Report-Only piece.
For more information on browser compatibility, policy testing and examples check out MDN Web Docs.
Now that I have a CSP, does that mean I am safe?
Not quite — but it certainly helps. CSP can block malicious script injections from the server side and XSS from the client side. Having a CSP is critical to keep your website from being blocklisted. When Google identifies malicious code, your website can become blocklisted, which can lead to reduced traffic and revenue for your site.
Although CSP is a critical piece of any website security solution, it does not provide comprehensive protection. Our free website scan can help you identify other vulnerabilities that your site may be facing. Talk to our team about your security strategy, and we can point you in the right direction.