A 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.
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.
A XSS attack is what happens 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 strict policy can prevent a myriad of issues that stem from loading scripts from unauthorized locations, be it XSS or content injections.
Follow along for a quick overview of Content Security Policies, how to write them, and how they get implemented.
Make a list of policies or directives and source values that state 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.
|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||media-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.
|*||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
Now let’s mix and match some common directives and source values and to address a few common scenarios.
Tip: When making a CSP, be sure to separate multiple directives with a semicolon
You want to prevent iFrames from loading on your site.
Content-Security Policy:script-src ‘none’
You want to allow images to load from any domain, but want to 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.
You only want to 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.
You want to 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.
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’
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.
Media source: docubrain.com
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:
<add name=”Content-Security-Policy” value=”default-src ‘self’; img-src*” />
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 the httpd.conf
It will look something like this depending on what directives you chose:
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
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
content=”default-src ‘self’; img-src *”>
Refer back to Set the HTTP Response Header for details to the software you use for your 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
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 gets blocklisted, blocking clients from access.
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.