Preventing XSS with ​Content Security Policy

Content Security Policy (CSP) is a W3C standard introduced to prevent Cross-Site Scripting (XSS), clickjacking and other attacks as the result of code injection in a web page. It is a computer security standard recommended by W3C Working Group which is supported by almost all major modern web browsers.

Content Security Policy (CSP) is a W3C standard introduced to prevent Cross-Site Scripting (XSS), clickjacking and other attacks as the result of code injection in a web page. It is a computer security standard recommended by W3C Working Group which is supported by almost all major modern web browsers. As of this writing, Content Security Policy Level 3 is the recommended W3C Working Draft per September 13, 2016.

According to W3C, “Content Security Policy (CSP), a tool which developers can use to lock down their applications in various ways, mitigating the risk of content injection vulnerabilities such as cross-site scripting, and reducing the privilege with which their applications execute.

CSP is not intended as a first line of defense against content injection vulnerabilities. Instead, CSP is best used as defense-in-depth. It reduces the harm that a malicious injection can cause, but it is not a replacement for careful input validation and output encoding.”


It is a type of computer security vulnerability that allows injection of malicious client-side scripts into the web page that modifies the normal flow of the application.  Attempts include by-pass the desired behavior, target server side systems such as database, and other security breaches. These types of attacks are done due to the presence of vulnerable, unsecure code and improper configuration.

How worse can it be?

Malicious script has access to all what a client-side script can do. It is as worse as it can peek into and modify the secure data illegally.

Browser objects: Cookies are the most vulnerable object for the malicious script which can get the session tokens to impersonate the user.

Database: Malicious script with XMLHttpRequest or AJAX can send requests to server to perform unauthorized access and modification to database data. CSRF tokens and session tokens can be easily tricked by peeking into the unprotected and unsecured cookies.

DOM: They can make arbitrary modifications to the web page, even trick the unaware user. Clickjacking is a part of such attack.

HTML5 APIs: Malicious scripts with some best engineering can access user’s geolocation, webcam, microphone from the modern browsers that leverage the support for HTML5 API that can perform such actions.


Consider an un-escaped PHP code like this in DOM:

<?= $_GET[‘query’]; ?>

This code gets the query string value for the key – query. So, when the URL is

Then DOM of the web page would just have:


Consider the attacker requests the URL like this:

content security policy

Fetch Directives

Fetch directives control the locations from where the resources can be loaded. By default, locations are wide open. default-src is the parent directive for all other fetch directives. When the value of default-src is set to then all fonts, script, style, objects, images can be loaded only from the specified location. To allow script to be loaded from a CDN such as cdnjs, then script-src needed to explicitly specify

In such case, the policy appears as: 

Content-Security-Policy: default-src; script-src

Similarly, loading images, styles, fonts can also be controlled by explicitly specifying appropriate directives. When any directive is not specified, it makes use of values supplied for default-src. Here in the example, images can be specified only when its location is in

Document Directives

These directives govern the policies that can be applied to documents. Base tag’s URL can be used in a document or not is decided by the value assigned to base-uri directive. Set of plugins that are allowed inside the document can be specified with plugin-types directive. Declaring this directive requires valid MIME type attribute to be set in the embed or object tag. The sandbox directive specifies the HTML sandbox policy which the user agent will apply to a resource when included in iframe.

Navigation Directives 

Two directives are available under navigation directives – form-action and frame-ancestors. The former allows form submissions only to the specified target location and the latter restricts URLs that can be embedded in the frame and iframe tags.

Reporting Directive 

This directive sends report to the specified location when any action has been prevented by CSP. As of CSP Level 3, report-uri has been deprecated and is present just for backward compatibility and will be removed in newer releases. Instead, report-to has to be used.

Real-time Sample 

Following is the CSP header of

content security policyPage Break


Overcoming XSS 

Refrain from using inline client-side scripts such as JavaScript and using eval functions inside the web page. They are more prone for cross-site attacks. Use default-src directive and set its value to ‘self’ and move all the inline codes to external script files and import them accordingly inside the webpage. By now, the CSP header will be:

Content-Security-Policy: default-src ‘self’

This prevents from editing or adding any inline client-side scripts inside the webpage directly. In the case, when it is necessary and unavoidable situation arises to use inline scripts, in two ways it can be allowed:

  1. unsafe-inline
    Adding this to default-src directive allows inline scripts to be added to the web page. But it is the bad practice that makes the CSP policy meaningless.
  2. nonce
    This is a step ahead than the previous. It just whitelists specific inline script using any cryptographic method. The entire inline script omitting the script tag along with any whitespace needs to be encrypted (say sha256 or sha384 or sha512). The encrypted key needs to be added to the CSP header for script-src directive. By now, the CSP header will be:

Content-Security-Policy: default-src ‘self’; script-src ‘sha256-hashvalue’

The script tag should add

<script nonce=hashvalue> 
  //Some inline code 


This is similar to the HTML5 attribute for iframes. Once defined in CSP policy header, it restricts the actions on the page rather than the resources. Unless specified explicitly, it prevents popups, plugins, script executions, origin, form submissions by default. It can take any of these values:

content security policy

Prevent Clickjacking

Usage of frame-ancestors can restrict the sources that can be embedded inside the web page. This directive can be applied to frames, iframes, and embed tags thereby preventing browsers from not allowing sources to be imported from other domains that are not specified in this directive.

Enforcing HTTPS 

In addition to all modifications, the protocol that is used must also be ensured. Not just the domain should have HTTPS to ensure secure connectivity, but all the sources, all the endpoints linked with the page should also be defined with secure protocol to ensure security by using the directive default-src with the value https:. In addition, any HTTP request that has been specified might need to be changed to HTTPS as well. CSP provides upgrade-insecure-requests directive to rewrite HTTP URLs to HTTPS. This directive is useful when website has enormous HTTP URLs that require manual modifications.

Reporting violation

Whenever the defined CSP rules are violated, report-to directive will help to report the violations to the location specified. This throws a SecurityPolicyViolationEvent every time a violation occurs. This exception include the following attributes:

content security policy

One can use third party reporting services such as to log the violation report and to view the reports in more organized view.


Content Security Policy (CSP) is just one of the method that is available to secure the web page from attackers especially Cross-Site scripting (XSS) attack. However, there are many other ways available that need to be incorporated to secure an application from massive attacks. Updating the software used or the policies applied regularly, protecting from day-to-day violation attempts, keeping server and application up-to-date with latest security updates and refraining the use deprecated and unsupported versions are some of the other ways to prevent attacks to the site.


About MST

At MST Solutions our cornerstone is to adapt, engage and create solutions which guarantee the success of our clients. The talent of our team and experiences in varied business verticals gives us an advantage over other competitors.

Recent Articles

Release Process

Release Process is a structured process with planning, scheduling, and controlling the project in each stage or environments with testing and deployments. It makes deployment stable and smooth.

Read Article »

Work with us.

Our people aren’t just employees, they are key to the success of our business. We recognize the strengths of each individual and allow them time and resources to further develop those skills, crafting a culture of leaders who are passionate about where they are going within our organization.