What is a Content Security Policy (CSP)?
A Content Security Policy (CSP) is a security feature used to help protect websites and web apps from clickjacking, cross-site scripting (XSS), and other malicious code injection attacks. At the most basic level, a CSP is a set of rules that restricts or green lights what content loads onto your website. It is a widely-supported security standard recommended to anyone who operates a website.
- What is a Content Security Policy (CSP)?
- Why do I need a Content Security Policy?
- 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
- Where do I set a CSP?
- Which vulnerabilities can a CSP protect against?
- How does a Content Security Policy work?
Why do I need a Content Security Policy?
Using a Content Security Policy adds a layer of protection to your website by defining what sources of content are allowed to load on a page. These rules help to defend against code injections and cross-site-scripting (XSS) attacks, two of OWASP’s top 10 Web Application Security Risks.
Protect against cross-site scripting
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.
Enforce HTTPs and prevent packet sniffing
To further enhance security, servers can whitelist domains and specify allowed protocols, such as requiring browsers to use HTTPS. A robust data transfer protection policy includes implementing HTTPS, securing cookies with a secure attribute, and auto-redirecting HTTP pages to HTTPS. Utilizing HTTP Strict-Transport-Security headers further ensures encrypted browser connections. These measures help prevent packet sniffing and maintain secure data transfers.
In addition to these security benefits, a CSP can also help improve the overall performance of your website by reducing the amount of benign (or malicious) content that’s loaded on your page.
How to set up a Content Security Policy
Follow along for a quick overview of Content Security Policies, how to write them, and how to implement a CSP for your environment.
Step 1 – Define your CSP
There are many different directives that can be used in a CSP, making it easy for you to customize your CSP to fit the needs of your website or application.
To get started, make a list of policies or directives and source values to define which resources your site will allow or restrict. We’ve provided a list of common CSP Directives and source values for you to mix and match.
Common CSP Directives & Examples
|script-src||script-src ‘self’ js.example.com;||Defines authorized sources for scripts|
|style-src||style-src ‘self’ css.example.com;||Defines authorized sources for stylesheets (CSS)|
|object-src||object-src ‘self’;||Defines authorized sources for plugins (ex: <object> or <embed>)|
|img-src||img-src ‘self’ img.example.com;||Defines authorized sources for images, or link element related to an image type (ex: rel=”icon”)|
|media-src||mia-src media.example.com;||Defines authorized sources for media elements (ex: <video>, <audio>)|
|frame-src||frame-src ‘self’;||Defines authorized sources for loading frames (iframe or frame)|
|font-src||font-src font.example.com;||Defines authorized sources where fonts files can be loaded from|
|connect-src||connect-src ‘self’;||Policy applies to connections from a XMLHttpRequest (AJAX) or a WebSocket|
|report-uri||report-uri /some-report-uri;||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.|
|add-header||add_header Content-Security-Policy “default-src ‘self’;”;||Allows you to add header for the Content Security Policy (CSP).|
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 that we’re familiar with the common directives and source values for a Content Security Policy, let’s go over some examples of CSP’s that address a few common website security scenarios.
Tip: When making a CSP, be sure to separate multiple directives with a semicolon.
Example 1 – Prevent iframes with frame-src:
Use frame-src to prevent iFrames from loading on your site.
Content-Security Policy:script-src 'none'
Example 3 – Restrict content other than images with img-src:
Use img-src to restrict content other than images from loading on your 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.
Example 4: Only allow same origin content with default-src:
Use default-src to allow only 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.
Example 5 – Only allow media or other executable scripts from same origin:
This combination allows images to load from anywhere but only allows 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.
Example 6 – Only allow images, scripts, form actions and CSS from same origin:
This combination allows images, scripts, form actions, and CSS from the same origin, but nothing else to load on the website.
default-src 'none'; script-src 'self'; img-src 'self'; style-src 'self';base-uri 'self';form-action 'self'
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.
Step 2 – Add the CSP to your HTTP Response Header
Where do I set a CSP?
Most modifications to your HTTP Response header will happen in the configuration file. Follow these steps to identify your server and set your CSP for the appropriate environment.
- 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.
Option 1: Set your CSP using 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 on.
- 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. Depending on the directives you chose, it will look something like this:
<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.
Option 2: Set your CSP using Apache
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 *"
Note: mod_headers is required to inject headers in Apache. More information at Apache HTTP Server Tutuorial.
Option 3: Set your CSP using NGINX
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 *"
You can find more information about HTTP security headers with NGINX here.
Now that you’ve tested out your CSP, it’s time to apply it to your production environment!
Step 3 – Apply your Content Security Policy
CSPs are typically implemented using a special HTTP header that is sent with the response from the server. The header contains the CSP rules, which are then enforced by the browser.
We are going to outline two ways to configure your system to start enforcing a CSP: The first option is to add your CSP via Meta tags, which works on all browsers, but is less popular. The second option is to set your CSP using the HTTP Response Header.
Option 1: Add your CSP via 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 for your environment.
<head> <meta http-equiv=”Content-Security-Policy” content=”default-src ’self’; img-src *”> </head>
Option 2: Add your CSP via 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 add Content-Security-Policy without the Report-Only piece.
Example CSP for Apache web server
For example, if you want to implement a live CSP for Apache, then add the following entry to your configuration file in /etc/apache2/sites-enabled/CSPexample.conf:
Header always set Content-Security-Policy "default-src 'self'; script-src *; style-src *; font-src *;img-src *"
Once you’ve saved the file, restart Apache to apply the changes and push it live to production.
Note: mod_headers is required to inject headers in Apache. More information at Apache HTTP Server Tutorial.
For more information on browser compatibility, policy testing, and CSP examples check out MDN Web Docs.
Which vulnerabilities can a CSP protect against?
A Content Security Policy can help you prevent attackers from accessing resources via insecure protocols.
CSP enables you to mandate the use of HTTPS protocol for any value specified in *-src attributes by appending the https:// prefix to any URL in your whitelist. This ensures resources never load over an unencrypted HTTP connection. You can also accomplish this by incorporating the block-all-mixed-content property.
Additionally, a Content Security Policy can help safeguard against the following vulnerabilities:
- Dynamic CSS using CSSStyleSheet.insertRule()
- Unsigned inline CSS statements in <style>
Ideally, you should maintain the script and CSS in distinct files referenced by the HTML page. If your site requires this functionality, you can activate it with unsafe-eval and unsafe-inline.
How does a Content Security Policy work?
A CSP is an added layer of protection for your website that can help detect and block malicious data injections and XSS from the client side. Attackers might launch these attacks against your website to infect it with malware, steal and harvest sensitive data from your server, launch phishing or SEO spam campaigns, or even deface it.
When a browser loads a page that has a Content Security Policy, it will check the CSP to see if the content on the page is allowed to load. If the content is not allowed, the browser will block it from loading, and will display an error message instead. This helps to prevent attackers from injecting malicious code into a page, and can help protect users from harmful attacks.
Implementing a Content Security Policy can also prevent your website from being flagged by search authorities. When Google identifies malicious code on your site it may become blocklisted, which can lead to reduced traffic, upset customers, damaged rankings, issues with brand reputation, and lost revenue for your site.
Although a CSP is an important component of any website security solution, it does not provide comprehensive protection. Our free website scan can help you identify other security threats that your site may be facing.
Talk to our team about your website security strategy, and we can point you in the right direction.