CSP – An Additional Layer of Security

  • Home
  • CSP – An Additional Layer of Security
CSP – An Additional Layer of Security
CSP – An Additional Layer of Security
CSP – An Additional Layer of Security
CSP – An Additional Layer of Security
CSP – An Additional Layer of Security

What is CSP?

Content Security Policy(CSP) is a set of rules that we can set to decide whether to restrict resources such as images, scripts, styles, and frames from being loaded and executed by a website, thus preventing various attacks.

We do not write the entire code for something we want to build. We fetch or load different types of content from different sources. For example, if you want to use any script, instead of writing an entire script, you source it to your WordPress website; either you can download and use it from local storage or fetch it directly through the Internet.

Content Security Policy is primarily used for preventing Cross-Site Scripting attacks, but it can also be used to prevent other attacks such as Clickjacking, packet sniffing and dangling markup attacks.

Why do we need CSP?

Website is attacked by various attackers to steal sensitive information, install malware, deface a website and many others.

Content-Security-Policy is an additional layer of security that helps to mitigate attacks such as XSS (especially DOM-based), Clickjacking, and data injection by restricting the resources to be loaded and executed by a website.

Websites often include a variety of resources such as scripts, images, fonts, and frames from different sources; such sources may contain compromised domains and malicious codes, which, when executed by the browser, can steal sensitive data and perform other actions. So, Content Security Policy is used to prevent this by giving control to the owners of the website to decide what sources of content should be allowed to load on the website.

Resources controlled by CSP.

1. Script Sources

This policy allows you to specify which scripts are allowed to be loaded and executed on a webpage. This is typically done by including the script source’s policy in the webpage. For example,

script-src ‘self’

This directive allows scripts to be loaded and executed only from the same origin.

2. Stylesheet sources

This policy allows you to specify which stylesheets are allowed to be loaded on a webpage by including their URL in the policy. For example,

style-src ‘example.com’

This directive allows stylesheets to be loaded only from the domain example.com.

3. Image Sources

The loading of the image can be controlled by specifying the allowed image sources in the policy. For example,

img-src ‘self’ example.com

This directive allows images to be loaded only from the same origin as the page and from the domain example.com.

4. Media Sources

This policy allows you to specify which media resources (e.g., audio and video) are allowed to be loaded by the webpage. For example,

media-src ‘self’

This directive allows media resources to be loaded only from the same origin as the webpage.

5. Object Sources

The loading of the plugins and other embedded contents can be controlled by specifying the allowed object sources in the policy. For example,

object-src ‘self’

This directive allows plug-ins and embedded contents to be loaded only from the same origin.

6. Font Sources

The loading of the font can be controlled by specifying the allowed font sources in the policy. For example,

font-src ‘self’ example.com

This directive allows the font to be loaded only from the same origin as the page and from the domain example.com.

7. Frame Sources

The loading of the content in frames and iframes can be controlled by specifying the allowed frame sources in the policy. For example,

frame-src ‘self’

This directive allows content in frames and iframes to be loaded only from the same origin as the webpage.

8. Connect Sources

The loading of resources from other domains via APIs such as XMLHttpRequest, WebSockets, etc., can be controlled by specifying the allowed connect sources in the policy.

connect-src ‘self’

This directive allows resources via APIs, such as XMLHttpRequest, WebSockets, etc., to be loaded only from the same origin.

Content Security Policy(CSP)

In the following diagram, we have taken an example of example.com, and we have set the Content Security Policy for all the resources as the same origin only. The first two requests will be allowed to load images and scripts as they are loading them from the same origin. But for the third request, it is not allowed because it violates the Content Security Policy as we are allowing to load our webpage as iframe for different origins.

Values of directives in CSP

1. nonce

A nonce is a unique value used only once, which is generated for the loading of each page and is embedded into that page. The value of the nonce is checked against the nonce value specified in the Content Security Policy header by the browser when the page is loaded. A resource is allowed to load and execute only if the value on the nonce in the header matches the nonce one that the resource contains.

Content-Security-Policy: script-src ‘nonce-xyz123’

In this example, nonce value xyz123 is included in the Content Security Policy header and is generated for each page load. For the script to be allowed to execute, this nonce value must also be added to the script tag.

Content Security Policy(CSP)

As the nonce in the script tag matches with the nonce value in the Content Security Policy header, this script will be allowed to execute.

Note: It is necessary for a nonce to be unpredictable.

2. hash

A hash is a unique value generated by applying a cryptographic hash function such as SHA3-256, SHA3-512 or MD5 to the contents of the resource. The hash value specified in the Content Security Policy header is checked against the hash value of the resource by the browser when the page is loaded. A resource is allowed to load and execute if the hash value in the header matches the hash value that the resource contains.

 Content-Security-Policy: script-src ‘sha256-HASH_VALUE’

In this example, HASH_VALUE is the hash of the script that is allowed to be executed when the page loads. For the script to execute, the HASH_VALUE in the Content Security Policy header should match the HASH_VALUE in the script.

Note: For maximum security it is recommended to use both nonce and hashes in your Content Security Policy header along with other security measures to ensure the safety of the web page.

3. self

The self is a keyword used in Content Security Policy directives which means the origin of the page itself. When self-value is used in a directive, the resources can only be loaded from the same origin itself.

default-src ‘self’ http://example.com

In this example, value self is used for directive self which means the default source for content on the page should be the same origin as the page itself, and it also allows content to be loaded from the origin http://example.com.

4. unsafe-inline

An unsafe-inline is a value used in Content Security Policy headers that allows inline scripts and styles to be loaded and executed on a webpage. It should be used with precaution because it allows malicious scripts to be executed on the webpage, which is also the reason it is called unsafe.  

script-src ‘self’ ‘unsafe-inline’;

In this example script-src directive allows the script to be executed from the same origin by value self, and the unsafe-inline value allows inline scripts to be executed.

5. unsafe-hashes

The unsafe-hashes is a value used in Content Security Policy headers which allows event-handlers or stylesheets to be loaded and executed on a webpage. Similar to unsafe-inline, it should be used with precaution because it allows malicious scripts to be executed on the webpage, which is also the reason it is called unsafe. 

script-src ‘self’ ‘unsafe-hashes’ ‘sha256-XYZ123==’;

In this example script-src directive allows the script to be executed from the same origin by value self, and the unsafe-hashes value allows the specific hash of an inline script.

6.  unsafe-eval

unsafe-eval is a value used in Content Security Policy headers that allows the use of the eval function and other dynamic code evaluation methods on a webpage. This value should be used with precaution because it allows malicious code to be executed on the webpage, which is also the reason it is called unsafe.   

script-src ‘self’ ‘unsafe-eval’;

In this example, the script-src directive allows the script to be executed from the same origin by value self, and unsafe-eval value allows the use of eval and other dynamic code evaluation methods.

Report Mechanism in CSP

Content Security Policy(CSP)

A Content Security Policy report is a mechanism to report at a specified endpoint, such as a server owned by a website or a third-party service. When a Content Security Policy is violated, this report can then be analyzed, and appropriate action can be taken.

The report-uri directive in the Content Security Policy header is used to implement the Content Security Policy report; this directive specifies the URL to which the browser should send the report. Websites can also test their Content Security Policy without actually enforcing it by using the Content-Security-Policy-Report-Only header. This header is useful for debugging and testing Content Security Policies before deploying them.

For example, suppose a Content Security policy is implemented that allows content to be loaded only from the same origin and blocks all other content to prevent Cross Site Scripting in the comment field of the website. If an attempt is made to post a malicious tag in the comment field with the source set to a third-party domain, it will violate the Content Security Policy. The script will be blocked from loading, and a report will be sent by the browser to the specified endpoint.

Content Security Policy(CSP)

Report Explanation

In this report document-uri specifies the URI of the document of the page where the violation occurred. The referrer specifies the URI of the page that referred the user to the document.  The violated-directive is the directive violated by the Content Security Policy. The blocked-uri is the URI of the resource that was blocked by the Content Security Policy. The original-policy is the policy that was originally defined in the Content Security Policy header. The source-file specifies the URI of the resource that caused the violation.

By analyzing the report, it is clear that if an attempt is made to load a script from the malicious domain, we can take appropriate action to block further attempts to mitigate any potential damage.

Mitigating Different Attacks

Content Security Policy(CSP)

1. Mitigating XSS(Cross Site Scripting) Attacks

In DOM-based cross-site scripting, we make use of sources to exploit our payload. This source is a potential vector of XSS, whether inline (adding the code directly to the website’s HTML) or from an external domain (loading a script from an infected website). XSS attack is possible because the browser trusts the source of the content.

We can reduce or eliminate Cross Site Scripting attack vectors by using Content Security Policy directives. For example

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

This directive specifies that we can load content only from the same origin, so by default, any type of content will be restricted by a different origin.

Content-Security-Policy: script-src ‘self’;

This directive specifies that we can load scripts only from the same origin and restrict loading scripts from a different origin. 

Content-Security-Policy: script-src ‘self’ http://example.script.com

This directive can be used to load script from the same origin and the specific domain http://example.script.com.

2. Mitigating Clickjacking Attack

Clickjacking attack is possible because of the overlapping malicious layer, which is visible to the victim and contains an innocuous resource that the victim is tricked to click on.

Content Security Policy can be used to mitigate Clickjacking by using the frame-ancestors directive. The frame-ancestors directive specifies the URLs of the website that are allowed to embed the current page in an iframe. For example, 

Content-Security-Policy: frame-ancestors ‘self’

This will restrict the pages of the website from being framed by a different origin.

Content-Security-Policy: frame-ancestors ‘none’ 

This will restrict framing from any origin.

Content-Security-Policy: frame-ancestors ‘self’ http://example.com

This will allow framing from the same origin and example.com.

We usually use X-Frame-Options header to mitigate Clickjacking Attacks, but using Content Security is more flexible because each frame can be validated, and also multiple domains and wild card can be used.

3. Mitigating Packet Sniffing Attack

Packet sniffing attacks occur when a malicious attacker is able to intercept the traffic and data is in a readable form.

In addition to restricting the locations from which content can be loaded, Content Security Policy can be used to specify which protocols to be used, that is, to make sure that data transfer is enforced through HTTPS only and thus mitigating the packet sniffing attack.

To allow https-only connections, the default-src directive can be used as

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

We can also specify https only for specific resource types such as image, script or style.

Content-Security-Policy: img-src https:;

Implementation of CSP

Content Security Policy(CSP)

There are two ways two write a Content Security Policy

1. By Using the HTTP header

The Content Security policy can be set as an http header which is sent in response to the web server. For example

Content-Security-Policy: default-src ‘self’; script-src ‘self’ https://example.com

In this example, the header name is Content-Security-Policy, and the value is the string that specifies the policy, which is the default-src directive.

2. By using the meta tag

The Content Security policy can be set using a meta tag in a webpage. For example

<meta http-equiv=”Content-Security-Policy” content=”default-src ‘self’; script-src ‘self’ https://example.com”>

In this example, we have used http-equiv, which specifies that the meta tag is equivalent to the HTTP header, and the attribute content is to specify the policy of the website. It is a string that defines the rules for the policy.

Setting the Content-Security policy as an HTTP header is preferred because HTTP headers are more flexible and can be set dynamically by the web server. Also, HTTP headers are processed before the content of the web page. However, the use of them depends on the specific use case and the requirements of the website.

Content-Security Policy can be implemented by using the following steps.

1. Write a policy

While implementing Content-Security-Policy, it is the first step to write a policy that specifies what resources should be loaded and executed by a website. This can be done by specifying the sources of the content that a website can load and execute, which can be a trusted third-party domain or our own domain.

2. Add the policy to your website.

After writing the security policy, it needs to be added to the website. This can be done simply by using one of the above methods, that is either by using the HTTP header of the meta tag.

3. Test your policy

After adding the policy to your website, the next step is to test and ensure that it works correctly. This can be done by using a tool called ESP evaluator which tests our policy and reports the issues that it finds.

4. Monitor your policy

The final step is to monitor your policy to ensure that it is up to date. This can be done by monitoring the logs and also the reports by the Content Security Policy for any violations.

Bypassing Content Security Policy

Content Security Policy is not a foolproof solution and can be bypassed by attackers in several ways.

1. Injecting into Trusted sources

Certain sources of content, such as trusted scripts and stylesheets, are allowed to be loaded by a Content Security Policy header. So, if an attacker is successful in injecting the malicious code into these trusted sources, then the browser will execute the code, and the restrictions imposed by the Content Security Policy will be bypassed. For example,

Content-Security-Policy: script-src ‘self’ https://trusted.com

In this example, we have configured a Content Security Policy header that will allow scripts to be loaded only from trusted.com, and an attacker can inject some malicious code into trusted.com, which will be executed by the browser bypassing the restrictions imposed by Content Security Policy.

2. CSP report evasion

When a policy is violated, a Content Security Policy Header can be configured to send a report to a server. Attackers can misuse this by creating malicious code that generates a report but still executes the code. For example

Content-Security-Policy: script-src ‘self’; report-uri https://example.com/csp-report

In this example, we have configured a Content Security Policy header that will send a report to the server when the policy has been violated. An attacker can craft a payload for generating a report but still execute a code as given below

Content Security Policy(CSP)

3. Misconfigured Policies

A Content Security Policy can be misconfigured, which will allow an attacker to find and exploit the loopholes, thus bypassing the restrictions imposed by the content security policy. For example

Content-Security-Policy: script-src *

In this example, the wild card is used, which means the script source can be any URL. An attacker can find and exploit this loophole in the policy and inject malicious code, which will be executed by the browser.

4. JavaScript string concatenation

Content Security Policy restrictions may only apply to script tags and not to inline scripts, which can be created using string concatenation in JavaScript. This can be misused by an attacker by dynamically generating a string that contains malicious code, which will not be restricted by the Content Security Policy header. For example,

Content-Security-Policy:  script-src ‘self’ https://trusted.com

In this example, we have configured a Content Security Policy header that will allow scripts to be loaded only from trusted.com. An attacker can generate a sting with malicious code and use it in an inline script, as given below

Content Security Policy(CSP)

5. History Manipulation

Attackers can manipulate the history of a webpage to inject malicious code into a page that would otherwise be restricted by a Content Security Policy header. For example

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

In this example, we have configured a Content Security Policy that will allow the script to be loaded only from its own domain. An attacker might try to inject a malicious script as given below

history.pushState({}, “”, “/malicious-page#<script>alert(‘XSS’);</script>”);

The history.pushState() method can be used by an attacker to change the URL of the page /malicious-page without reloading it and adding a URL fragment that contains a malicious script. As the URL fragment is a part of the URL and not sent to the server, the browser does not know that the content of the page has changed and will execute the malicious script even though Content Security Policy allows the script to be loaded from the same domain.

6. Domain tampering

An attacker to tamper with the domain name of the page to bypass restrictions imposed by the Content Security Policy. For example,

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

In this example, the policy allows scripts to be loaded only from the same domain. An attacker can change the domain and then execute malicious scripts on the webpage, as shown below, that would have normally been blocked by Content Security Policy.

document.domain = “attacker.com”;

7. CORS exploitation

An attacker can exploit CROSS-Origin Resource Sharing to bypass the restrictions imposed by the Content Security Policy. For example,

Content-Security-Policy: default-src ‘self’; connect-src ‘*’;

In this example, the policy allows the web page to make request to any domain by the content-src ‘*’ directive. This can be exploited by an attacker by creating a malicious website that returns sensitive information and then tricking a user into visiting the malicious website.

8. File Upload

If a web application allows users to upload images or files and has a Content Security Policy that disallows the execution of any scripts loaded explicitly, then if it does not properly validate the files or images, an attacker can upload malicious scripts through files or images which could be executed by the browser and allow the attacker to steal sensitive information.

9. unsafe-inline

The value unsafe-inline allows the execution of scripts, styles and event handlers. An attacker can make use of Inline scripts, JavaScript URLs, Event handlers and Dynamic scripts for bypassing CSP using the value unsafe-inline.

Content-Security-Policy: default-src ‘self’; script-src ‘self’ ‘strict-dynamic’

In this example, the policy allows execution of script only from the same origin and from scripts that can be previously loaded. If the attacker discovers a vulnerability in a website that allows injecting malicious code whose execution would have normally been blocked by CSP, but if an attacker makes use of an unsafe-inline directive, the policy can be bypassed, such as

<img scr=x onerror=”alert(‘CSP bypassed’)” />

This code would have been normally been blocked by CSP, but if the attacker adds the unsafe-inline keyword to the policy.

Content-Security-Policy: default-src ‘self’; script-src ‘self’ ‘strict-dynamic’ ‘unsafe-inline’

It would allow the payload to be executed and CSP to be bypassed. Hence developers should be careful when using this keyword and used it only when it is absolutely necessary.

10. unsafe-eval

The value unsafe-eval allows the use of the eval function and other dynamic code evaluation methods on a webpage. An attacker can use the unsafe-eval keyword to bypass Content Security Policy by injecting code that calls the eval function.

script-src ‘self’

This policy allows scripts to be loaded only from the same origin, but suppose we are using jQuery, which uses the eval function. This policy will prevent jQuery from functioning correctly. For jQuery to work properly, we will have to change the policy to

script-src ‘self’ ‘unsafe-eval’

This policy not only allows scripts to be loaded only from the same origin but also allows scripts that use the eval function, such as those used by jQuery. If the attacker discovers a vulnerability in a website that allows injecting their own script that also uses the eval function, the CSP will be bypassed, and attackers can steal sensitive data.

How SecurityBoat Protects You

Cyber Attacks are increasing day by day. In the ocean of the Internet, Every Industry is prone to cyber-attacks. We live in a time where data breaches, ransomware attacks, and social engineering are well known. Cyber-attacks have been reported in diverse industries, including health care, government, telecom, and other business leading to data breaches and financial losses for those organizations. In SecurityBoat, we identify the potential existing risk before any malicious attacker can gain access to that information. SecurityBoat provides services that make sure your data is protected from unauthorized access. With SecurityBoat, we ensure that your infrastructure is protected to the fullest extent possible.

Conclusion

Content Security Policy is the most important and valuable security measure that can help protect your website and your users from various types of attacks, such as Cross Site Scripting, Clickjacking, Packet sniffing and many others. By implementing a Content Security Policy in a proper way, you can help keep your website safe and secure and provide a better experience for your users.

References

PortSwigger article

Report-URI

CSP reference guide

OWASP article

Mozilla Article

Our latest blogs are available here.