Content Security Policy
Introduced in November 2012, Content Security Policy presents an extra layer of security against multiple vulnerabilities such as XSS, Clickjacking, Protocol Downgrading and Frame Injection. It appears that CSP will become the most significant tool for client side security in the near future, since it provides a substitute for security headers, such as X-Frame-Options and X-XSS-Protection, that aren’t enabled by default.
Here is a sample CSP header:
Content-Security-Policy: ;
Copy
In CSP, we use a whitelist to define rules. With this approach, we can filter out any resources that do not fit with our rules. All we have to do is to state the resources within the Content-Security-Policy response header:
Content-Security-Policy: script-src 'self' https://apis.google.com
Copy
This CSP directive allows script loading only over our domain and https://apis.google.com. Any other inline scripts will not run.
Content Security Policy Directives
Along with the CSP header, we can use the following directives to further limit and define the use of resources.
default-src Directive Example
By default these directives are unrestrictive, meaning that if they are not declared in the CSP header, any request will go through. So, if no value is given for style-src, this will be interpreted as style-src: * and styles from all sources will be allowed.
We can use the default-src directive to change this. The specified value will override most directives ending with -src by setting a default value for them. If we define default-src as http://www.example.com and don’t set a value for font-src, the fonts can only be loaded from https://www.example.com.
However, default-src cannot override these directives:
- base-uri
- form-action
- frame-ancestors
- plugin-types
- report-uri
- sandbox
We can add more than one directive in one HTTP header by separating them with a semicolon:
script-src https://host1.com https://host2.com; style-src https://www.example.com
Copy
Multiple values for a directive must be separated with a space:
script-src https://host1.com https://host2.com;
Copy
One Thing To Keep in Mind When Using Content Security Policy
Define CSP for each page set in the HTTP response. This will help you define the optimal policy for each page and its specific needs.
You can learn more about Content-Security-Policy (CSP) on the Netsparker Blog.
Directive | Description |
base-uri: | The base HTML element contains the absolute URL that is prepended to all the relative URLs on the page. This directive helps us restrict the URLs that are allowed to be used in the base HTML element, and therefore prevent Base Tag Hijacking attacks. |
child-src: | This directive allows us to define which websites are permitted to be loaded in frames located on the page. We can use it as an extra precaution to protect our page from Frame Injection attacks. |
connect-src: | This directive restricts the resources that can be loaded via script interfaces such as XHR or WebSockets. This prevents attackers from stealing data from the site. |
font-src: | This directive specifies the font sources that can be loaded using @font-face. It is mostly used to prevent attackers from sending extracted data back to their server using the @font-face src directive. |
form-action: | This directive specifies the URLs that can be used as targets for form submissions. It can be used as an extra precaution to protect pages from Form Tag Hijacking and Cross-Site Scripting attacks. |
frame-ancestors: | This directive specifies the sites that have the authority to load the current page in a frame, iframe, object, embed, and applet tag. It is a substitute for X-Frame-Options, since it can also help prevent Clickjacking and UI Redressing attacks. |
img-src: | This directive defines the sources from which images can be loaded. |
media-src: | This directive defines or restricts the sources from which video and audio can be loaded. |
object-src: | This directive defines or restricts the sources from |
plugin-types: | This directive defines or restricts the plugin types that can be loaded. |
report-uri: | This directive specifies the URLs that will receive the report when a CSP directive is violated. |
style-src: | This directive defines or restricts the sources for CSS files. This allows you to avoid data exfiltration via CSS. |
upgrade-insecure-requests: | This directive converts the HTTP requests to HTTPS. |
Prevent XSS, clickjacking, code injection attacks by implementing the Content Security Policy (CSP) header in your web page HTTP response. CSP instruct browser to load allowed content to load on the website.
All browsers don’t support CSP, so you got to verify before implementing it. There are three ways you can achieve CSP headers.
- Content-Security-Policy – Level 2/1.0
- X-Content-Security-Policy – Deprecated
- X-Webkit-CSP – Deprecated
If you are still using the deprecated one, then you may consider upgrading to the latest one.
There are multiple parameters possible to implement CSP, and you can refer to OWASP for an idea. However, let’s go through the two most used parameters.
Parameter Value | Meaning |
default-src | Load everything from a defined source |
script-src | Load only scripts from a defined source |
The following example of loading everything from the same origin in various web servers.
Apache
Get the following added in httpd.conf
file and restart the webserver to get effective.
Header set Content-Security-Policy "default-src 'self';"
Nginx
Add the following in the server block in nginx.conf
file
add_header Content-Security-Policy "default-src 'self';";
Microsoft IIS
Go to HTTP Response Headers for your respective site in IIS Manager and add the following

Check out this to implement frame-ancestors using CSP. This is an advanced version of X-Frame-Options.