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.
Contents:
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.
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.
A content security policy can help prevent script-injection attacks from occurring because it can be set up to limit JavaScript to loading only from trusted places. Leveraging a strict policy can prevent a myriad of issues that stem from loading scripts from unauthorized locations, be it XSS or content injections.
You can use a CSP to help prevent your web pages from executing inline or remote scripts. Attackers are known to inject malicious JavaScript from their servers in various types of website malware, so by simply restricting what scripts are allowed to execute you can make a significant step to securing your website.
Clickjacking lures unsuspecting site visitors into clicking on some object which triggers an action on a different, iframed website. Triggered actions might include deleting a user, updating permissions, or any other action normally done via clicks on the targeted website. Clickjacking can be used to steal sensitive information, such as login credentials, or even trick unsuspecting victims into downloading malware.
Fortunately, the Content Security Policy frame directive frame-ancestors can be used to instruct the browser not to allow frames from other domains to help prevent clickjacking attacks.
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.
Follow along for a quick overview of Content Security Policies, how to write them, and how to implement a CSP for your environment.
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.
Directive | Example | Description |
---|---|---|
default-src | default-src ‘self’ cdn.example.com; | Default policy, used in any case (JavaScript, Fonts, CSS, Frames etc.) except if overridden by a more precise directive. |
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: or ) |
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: , ) |
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). |
Here is a list of common source values for -src directives.
Value | Example | Description |
* | 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 bodies and javascript: URIs |
‘unsafe-eval’ | script-src ‘unsafe-eval’ | Allows use of unsafe dynamic code evaluation like JavaScript eval() |
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.
Use frame-src to prevent iFrames from loading on your site.
Content-Security-Policy:frame-src 'none'
Use script-src to prevent JavaScript from loading on your site.
Content-Security Policy:script-src 'none'
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.
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.
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.
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 out your CSP to make sure you didn’t forget to include any trusted domain origins your site needs.
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.
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:
; img-src*” />
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.
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!
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.
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 in the so it begins working ASAP for your environment.
head> meta http-equiv=”Content-Security-Policy” content=”default-src ’self’; img-src *”> /head>
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.
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.
Crafting a Content Security Policy (CSP) that aligns perfectly with your unique needs can present a challenge. Thankfully, a variety of free tools are available to assist with generating, evaluating, and monitoring your CSP.
Incorporating these tools into your web application development workflow can facilitate consistent automatic checks, though regular manual audits are still essential:
While these tools streamline the process and offer a valuable automatic check, remember they supplement — not substitute — the need for manual audits. Regularly conducted manual auditing is a requisite to ensure a secure and robust CSP.
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:
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.
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.
Rianna MacLeod is Sucuri’s Marketing Manager who joined the company in 2017. Her main responsibilities include ghost-writing technical content, SEO, email, and experimentation. Rianna’s professional experience spans over 10 years of technical writing and marketing. When Rianna isn’t writing words, you might encounter her hiking in the forest or at the beach. You can find her on Twitter and LinkedIn.