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.”
CROSS-SITE SCRIPTING (XSS)
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||HTTP Header Name|
Aspects of site’s behavior are defined using directives. Content Security Policy (CSP) has rich set of directives that grant developers control what resources are allowed and what are not allowed inside the webpage. Following is the graphical representation of directives available in CSP Level 3.
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 https://www.example.com 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 https://cdnjs.cloudflare.com/.
In such case, the policy appears as:
Content-Security-Policy: default-src https://www.example.com; script-src https://cdnjs.cloudflare.com
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 https://www.example.com.
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.
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.
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.
Following is the CSP header of http://www.twitter.com
CSP IN ACTION
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:
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.
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 </script>
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:
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.
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.
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:
One can use third party reporting services such as https://report-uri.io/ 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.