www.invicti.com Open in urlscan Pro
2606:4700::6812:918  Public Scan

Submitted URL: https://www.netsparker.com/blog/web-security/negative-impact-incorrect-csp-implementations/
Effective URL: https://www.invicti.com/blog/web-security/negative-impact-incorrect-csp-implementations/
Submission: On September 22 via api from GB — Scanned from GB

Form analysis 3 forms found in the DOM

GET https://www.invicti.com/

<form role="search" method="get" class="sub-nav-search-form" action="https://www.invicti.com/" __bizdiag="115" __biza="W___">
  <input type="text" placeholder="Type here to search..." name="s">
</form>

POST https://netsparker.us18.list-manage.com/subscribe/post?u=5b95175e9d922bf109568e064&id=c41662cd70

<form action="https://netsparker.us18.list-manage.com/subscribe/post?u=5b95175e9d922bf109568e064&amp;id=c41662cd70" method="post" target="_blank" class="maillist-subscribe" __bizdiag="66081660" __biza="W___">
  <input class="form-control" name="EMAIL" placeholder="Enter your email to signup for the latest posts" type="email" required="" value="">
  <button type="submit" class="btn btn--primary">Subscribe</button>
</form>

POST https://netsparker.us18.list-manage.com/subscribe/post?u=5b95175e9d922bf109568e064&id=c41662cd70

<form action="https://netsparker.us18.list-manage.com/subscribe/post?u=5b95175e9d922bf109568e064&amp;id=c41662cd70" method="post" target="_blank" class="maillist-subscribe" __bizdiag="66081660" __biza="W___">
  <input class="form-control" name="EMAIL" placeholder="Email" type="email" required="" value="">
  <button type="submit" class="btn btn--primary">SUBSCRIBE</button>
</form>

Text Content

Netsparker is now Invicti
Get a demo
AppSec with Zero Noise Get a demo
Get a demo
 * Product
   * Overview
   * Features
 * Why Us?
   * Solutions
     * Industries
       * IT & Telecom
       * Government
       * Financial Services
       * Education
       * Healthcare
     * Roles
       * CTO & CISO
       * Engineering Manager
       * Security Engineer
       * DevSecOps
   * Comparison
   * Case studies
   * Customers
   * Testimonials
 * Plans
 * About Us
   * Our Story
   * In the news
   * Careers
   * Contact us
 * Resources
   * Blog
   * White Papers
   * Webinars
   * Resource Library
   * Invicti Learn
   * Partners
     * Channel
     * MSSP
   * Support


Web Security Blog
 * Web Security
 * News
 * Product Releases
 * Product Docs & FAQs


Search Close search bar


THE DANGERS OF INCORRECT CSP IMPLEMENTATIONS

Sven Morgenroth - Tue, 06 Nov 2018 -
 * 
 * 
 * 

This post examines incorrect CSP implementations on the New Yorker and Blogger
and points out common issues in CSP implementations. You will also learn how to
fix such problems, check if your CSP implementation is problematic, and test it
in Report Only monitoring mode. The article also lists CSP directives and
keywords, and demonstrates how to use them correctly.

Subscribe

Your Information will be kept private.

Stay up to date on web security trends
SUBSCRIBE

Your Information will be kept private.

Content Security Policy (CSP) is an effective client-side security measure that
is designed to prevent vulnerabilities such as Cross-Site Scripting (XSS) and
Clickjacking. Following the regular discovery of bypass techniques, a group of
researchers led by Google managed to fix these weaknesses in CSP version 3.0.
With each new bypass that surfaces, browser developers continue to strengthen
CSP.

However, bypasses aren’t the only issue with CSP. Incorrect CSP implementations
can also pose critical problems. Keeping in mind that security is not a one time
fix but a process, we’re convinced that a significant portion of a secure CSP
policy lies in understanding and implementing it correctly.


INCORRECT CSP IMPLEMENTATIONS

Useless CSP reports all websites that have incorrectly implemented CSPs. Let’s
take a look at some examples.


INCORRECT CSP IMPLEMENTATION ON THE NEW YORKER

In our first example, let’s look at the CSP header from the HTTP response of The
New Yorker of August 31, 2018:

Content-Security-Policy: default-src https: data: 'unsafe-inline' 'unsafe-eval';
 child-src https: data: blob:;
 connect-src https: data: blob:;
 font-src https: data:;
 img-src https: blob: data:;
 media-src blob: data: https:;
 object-src https:;
 script-src https: data: blob: 'unsafe-inline' 'unsafe-eval';
 style-src https: 'unsafe-inline';
 block-all-mixed-content;
 upgrade-insecure-requests;
 report-uri 
https://capture.condenastdigital.com/csp/the-new-yorker

A quick analysis reveals the following:

 * The CSP commands unsafe-inline and unsafe-eval allow inline scripts and
   scripts from event attributes to execute, something that is highly damaging
   to the website’s client-site security
 * Really, the only good thing about the header above is that it enforces HTTPS


INCORRECT CSP IMPLEMENTATION ON BLOGGER

Another incorrectly implemented CSP header reported on Useless CSP was found on
Google’s blog service, Blogger:

content-security-policy: script-src   'self' *.google.com *.google-analytics.com 'unsafe-inline' 'unsafe-eval' *.gstatic.com *.googlesyndication.com *.blogger.com   *.googleapis.com uds.googleusercontent.com https://s.ytimg.com https://i18n-cloud.appspot.com   www-onepick-opensocial.googleusercontent.com www-bloggervideo-opensocial.googleusercontent.com www-blogger-opensocial.googleusercontent.com https://www.blogblog.com; 
report-uri /cspreport

Yet again, note the unsafe-inline and unsafe-eval keywords, which effectively
disable any script execution restrictions that were put in place by the
whitelisting of certain websites. This was an eye-watering discovering,
considering Google is among the leading companies promoting the development of
CSP.


LESSONS FROM THESE MISTAKES

 * These errors demonstrate the fact that everyone makes mistakes, showing how
   important it is to use an automated web application security scanner which
   will detect them for you.
 * It’s not always easy to add CSP to an existing website. There are many
   factors developers need to consider when they need to decide from where
   external resources should be loaded. This involves caching, available
   bandwidth and general performance. Security often ranks low on the list of
   considerations. In order to effectively implement CSP, you either need to
   consider it before writing the application (the easiest option) or find a way
   add it on top of your existing applications with the tools CSP provides, most
   notably nonces and hashes.
 * The problem with these examples are the commands unsafe-inline and
   unsafe-eval, which remove most of the protections CSP provides against Cross
   Site Scripting.


HOW TO ENSURE A GOOD CSP SETUP

CSP version 3.0 introduced the option to whitelist code blocks using the
strict-dynamic directive. Strict-dynamic (covered in detail later in the post)
allows some unsafe options such as unsafe-inline and unsafe-eval to be
overridden in CSP 3.0. Whitelisting the data: protocol in script-src and
default-src directives lays the grounds for attacks such as the following:

www.victim.com/index.php?jsfile=data:,alert(1)
<script src="data:,alert(1);"></script&gt;

You can find more examples on the Useless CSP website.


COMMON ISSUES IN CSP IMPLEMENTATIONS AND HOW TO FIX THEM

An incorrect CSP header implementation not only impacts the security of your
website but can also affect its operation. Websites today rely heavily on
third-party sources. These resources are often loaded from the subdomains of the
same website (e.g. static.example.com, scripts.example.com).

The use of inline scripts and JavaScript code in event handlers of HTML elements
is quite popular among developers, but that habit isn’t really compatible with
CSP. It’s clever to move inline scripts to a subdomain instead, and load them as
an external script. Additionally, the host of all the external scripts must be
whitelisted in your Content Security Policy, even if you own the subdomains from
which the scripts are loaded.


HOW TO CHECK IF YOUR CSP IMPLEMENTATION IS PROBLEMATIC

In practice, there are only three ways to find out whether you’ll have a problem
in the implementation of CSP:

 * You could visit every page and check for errors in your browser’s developer
   console
 * You could wait for the customer complains that your site doesn’t work
   correctly
 * You could use the CSP Report-Only mode

Naturally, we recommend the third option.


TESTING CSP IMPLEMENTATIONS IN THE REPORT-ONLY CSP MONITORING MODE

But how does the report-only mode work? Before publishing the CSP headers on
your website, you can try them in Report-Only mode. In Report-Only mode, the CSP
directives are not enforced. Instead the browser reports issues regarding the
CSP to an end-point specified in the report-uri attribute. This way, you can
find any missing directives, the changes you need to implement and the links you
have to whitelist in the CSP header – before you enforce these rules. In
addition, it helps you to detect inline JavaScript codes and styles and move
them into their respective external file.

Here is an example:

Content-Security-Policy-Report-Only: script-src 'self'; report-uri /my_amazing_csp_report_parser;

This sample script-src directive exclusively whitelists its own origin. All
script loadings, inline scripts and script codes in event attributes coming from
any other origin will trigger the CSP to send a notification to the end-point
specified in the report-uri attribute.

After the testing is complete and you’re ready to push your CSP commands live,
you’ll have to disable the Report-Only mode for them to be effective.

This is what the code would look like:

Content-Security-Policy: script-src 'self'; report-uri /my_amazing_csp_report_parser;

Note that even though some CSP directives can be set using HTML’s meta tags,
when in Report-Only mode you cannot do that and have to use an HTTP response
header instead. This screenshot shows how Netsparker reports ineffective
Report-Only CSP directives in an HTML meta tag.




CONTENT SECURITY POLICY DIRECTIVES

In addition to the CSP header, Content Security Policy has many directives that
allow you to configure the security of your websites.

This table lists and explains the directives that can be used to further limit
and define the use of resources.

DirectiveDescriptionbase-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 <object>, <embed>, and <applet>,
which helps preventing Cross-Site Scripting attacks.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.

EXAMPLES OF USING CSP DIRECTIVES CORRECTLY

Here are a few examples of how to use CSP directives effectively.

DEFAULT-SRC DIRECTIVE EXAMPLE

By default, these directives are unrestrictive, meaning that if they are not
declared in the CSP header, any request will be allowed through. So, if
style-src is not set, this will be interpreted as style-src: * , allowing styles
from all sources.

You 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 you set default-src to http://www.example.com, and don’t set a value for
font-src, the fonts can only be loaded from http://www.example.com.

However, default-src cannot override these directives:

 * base-uri
 * form-action
 * frame-ancestors
 * plugin-types
 * report-uri
 * Sandbox

This is how Netsparker reminds you that default-src does not affect certain
directives.



OBJECT-SRC TO BLOCK PLUGINS

We stated above that CSP is a major mechanism in client-based security against
various vulnerabilities like XSS. XSS attacks are generally carried out by
script executions, so it would seem that limiting the script and style resources
as a precaution might be the best way to mitigate against it. However, there are
other HTML elements that can run JavaScript code, such as <embed>, <object> and
<applet>.

This is how Netsparker shows that missing the object-src directive in CSP can
lead to XSS.



You might not want to set the default-src since it’s a fallback mechanism and
for the reasons stated above. You’ll probably never want to set it to none.
However, you might want to block plugin loadings. In this case you can set
object-src to none regardless of whatever you set for default-src.

Example:

Content-Security-Policy: default-src 'self'; object-src 'none';

This option will block plugins from loading on your webpage.


THE KEYWORDS THAT SHAPE THE CSP DIRECTIVES

Aside from specifying origins from which resources can be loaded, CSP also
offers you a few keywords that allow you to further refine your CSP.

KeywordsDescription‘none’:As the name suggests, nothing is allowed towill be
embedded. For example, the object-src: ‘none’ command will not embed any objects
on the page.‘self’:This matches the origin of the current webpage. Resources
from other origins including subdomains will not be loaded.‘unsafe-inline’:This
allows the use of inline JavaScript and CSS.‘unsafe-eval’:This allows the use of
text-to-JavaScript functions like eval().


SETTING CSP IN META TAGS

Even though CSP is mostly used to define the directives in HTTP responses, you
can set CSP in meta tags, too. This is ideal for situations in which you can’t
set HTTP response headers:

<meta http-equiv="Content-Security-Policy" content="default-src https://cdn.example.net; child-src 'none'; object-src 'none'">

Unfortunately the following directives cannot be used when setting CSP between
meta tags:

frame-ancestors, sandbox, report-uri




BYPASSING EVAL FUNCTION RESTRICTIONS

Use of the functions eval, new Function(), setTimeOut and setInterval, which run
the text inputs within the document context, is automatically blocked by CSP. To
mitigate this, you must make a few changes to the code:

 * If the JSON parsing is carried out using the eval function, you should use
   the JSON.parse function
 * The strings used in setTimeout or setInterval functions have to be changed to
   inline functions:

Instead of:

setTimeout("document.querySelector('a').style.display = 'none';", 10);

use:

setTimeout(() => document.querySelector('a').style.display = 'none', 10);

 * If your template system uses generic functions such as new Function(), you
   can use a system that supports CSP out-of-the-box, such as Angular. You can
   also use pre-compilation if your template system supports it.

You can use the unsafe-eval keyword if you really have to use text-to-Javascript
functions like eval. However, be warned that you’ll be creating a huge security
gap in the CSP mechanism.

script-src: 'unsafe-eval'


BENEFITS OF REORGANIZING YOUR CODE

An origin-based limitation mechanism could have solved a lot of problems.
However, even if an origin-based mechanism was implemented, there’s would still
be a large void in the XSS side, Inline Injection:

<script>alert(123);</script>
<a href= onclick="javascript:alert(123)">Click me!</a>
<img src=1 onerror="alert(1);"/>

CSP fixes this problem by blocking inline scripts. Not only does CSP block the
codes found between the script codes, but it also blocks the script in event
attributes and javascript: URLs.

Therefore you should reorganize the code within the script tags as external
files on your website. Doing so has a few benefits:

 * Having the external files cached by the browser will improve the website
   performance
 * The code will be cleaner
 * Since you will need to minimize the JavaScript code in order to allow fast
   loading times, this will also make it slightly harder for attackers to find
   out what it does and how to exploit it

If you still insist on using inline Javascript and CSS, you must specify it
within the appropriate directives:

script-src: 'unsafe-inline'; style-src: 'unsafe-inline'


SHOULD YOU USE NONCE OR HACK IN THE WHITELIST?

When using CSP to whitelist script or style sources, you’re not limited to
origin-based whitelisting the safe resources. You can also use nonce or hash
functions to whitelist code blocks.

Let’s assume  you have a code block as below:

<script nonce=EDNnf03nceIOfn39fn3e9h3sdfa>
  //Some inline code I cant remove yet, but need to asap.
</script>

Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'

You can whitelist the entire code block with a nonce value. As a security
measure, for each request, a new nonce value has to be generated, it cannot be
reused and has to be random and long.

On the other hand, while using hash instead of a nonce attribute, you can obtain
a hash for the script and whitelist it in the respective header.

<script>
alert('Hello, world.');
</script>

Content-Security-Policy: script-src 'sha256-qznLcsROx4GACP2dm0UCKCzCG-HiZ1guq6ZZDob_Tng='

CSP supports SHA256, SHA384, and SHA512 hash algorithms.


DEPRECATED CSP DIRECTIVES

Like any other technology, CSP has developed over time and some directives have
been deprecated. You should know that the X-Content-Security-Policy and
X-Webkit-CSP directives have been deprecated. Instead you can use the
Content-Security-Policy directive.


SECURITY RESEARCH ON CSP 3.0

A few years ago, researchers from Google released CSP is Dead, Long Live CSP, a
risk analysis report on frequently used CSP headers. The research was one of the
most comprehensive of its kind, covering 1,687,000 hostnames and 26,000 CSP HTTP
headers. It also analyzed the three popular methods used to bypass CSP. These
are Open Redirection, Insecure JSONP Endpoint, and AngularJS CSP Compatibility
Mode.


INSECURE ENDPOINT VULNERABILITIES DUE TO PERMISSIVE CSP CONFIGURATIONS

The report stated that in the script loadings, 14 out of 15 whitelisted domains
have insecure endpoint vulnerabilities and attacks targeting them will
deactivate the CSP policies.

Here are a few examples of the famous CSP bypassing methods listed in the
research.

Bypassing CSP path restrictions:

Open Redirection:

Content-Security-Policy: script-src example.org partially-trusted.org/foo/bar.js

// Allows loading of untrusted resources via:
<script src="//example.org?redirect=partially-trusted.org/evil/script.js">

XSS CSP whitelist bypasses

Insecure JSONP Endpoint

<script src="/api/jsonp?callback=evil"></script>

AngularJS CSP Compatibility Mode

<script src="angular.js"></script>

<div ng-app>{{ executeEvilCodeInUnsafeSandbox() }} </div>


USING NONCE-BASED CSP FOR DYNAMIC UPLOADS

Google suggests taking control of CSP policies by using nonce-based policies
with dynamic uploads instead of whitelist-based policies. Google started
supporting the strict-dynamic method to implement the policy it suggests to
users on its own browsers. Let’s take a closer view at how this method works.

You’ll load a script over example.com/map.js. So you specify a CSP for it:

Content-Security-Policy: script-src example.com;

You trust example.com, but you also use the unsafe-inline directive to avoid the
objects loaded to DOM from being stuck at the CSP barrier – a small concession
for you but a large weakness for the attackers.

Content-Security-Policy: script-src example.com 'unsafe-inline';

Besides, by whitelisting the example.com domain in the beginning, we cracked the
door open for CSP bypasses from various attack parameters on example.com. Now
let’s assume that there’s an open redirection in example.com (note this example
below only works in older browsers):

example.com/redirectme.php?go=http://attacker.com/bad.js

If you used nonce-based CSP instead, you would’ve gotten rid of any potential
attack vector:

Content-Security-Policy: script-src 'nonce-random-123' 'strict-dynamic';

<script src="http://example.com/map.js" nonce=random-123></script>

The above only trusts the script from example.com/map.js by assigning a nonce
value to the code block where the script is loaded. By using strict-dynamic, you
allow DOM manipulations to be made from this block and even allow scripts to be
loaded by the whitelisted JavaScript code. By doing so, you didn’t have to
whitelist the entire example.com domain nor use unsafe-inline or unsafe-eval for
the loading of dynamic resources, which protects your website from various
attacks.

BACKWARD COMPATIBILITY WITH EARLIER VERSIONS OF CONTENT SECURITY POLICY

The attribute nonce has been supported since CSP 2.0, and strict-dynamic was
introduced in CSP 3.0. So what should you do if the user’s browser does not
support CSP 2.0 and you’re using nonce? One option is to use the unsafe-inline
directive alongside nonce as a backward compatibility method, as shown:

Content-Security-Policy: script-src 'nonce-B92E8649B6CF4886241A3E0825BD36A262B24933' 'unsafe-inline'
<script nonce="B92E8649B6CF4886241A3E0825BD36A262B24933">
console.log("code works");
</script>

When nonce is present, the unsafe-inline command is ignored by the browser. So
in browsers that support CSP 2.0 and above, the unsafe-inline command will not
be taken into consideration. In browsers where nonce isn’t supported (CSP 1.0),
unsafe-inline will be put to work and your page will continue functioning. The
backward compatibility implementation for strict-dynamic is as follows:

Content-Security-Policy: script-src 'nonce-B0A48531D5C5EB3F8503430E6D75C83E23B7AE36' 'strict-dynamic' https: http:

With the use of strict-dynamic, the browsers that support CSP 3.0 and above will
also ignore the https: and http: commands.


CONCLUSION

Content Security Policy is an extensive security measure. With the release of
new versions and the discovery of new attack patterns, CSP is evolving.
Independent research reveals the dangers of a incorrectly implemented CSP
header. Therefore, implementing the correct modification is crucial to ensure
the safety and functionality of our websites. This is why we recommend that you
scan your web application with the Netsparker web security solution, which
checks your CSP configuration and alerts you if it detects an unsafe
implementation.

Article written by Netsparker security researchers:

Ziyahan Albeniz
Umran Yildirimkaya
Sven Morgenroth


ABOUT THE AUTHOR

Sven Morgenroth - Senior Security Engineer




RELATED ARTICLES


USING CONTENT SECURITY POLICY (CSP) TO SECURE WEB APPLICATIONS


THE END OF COINHIVE AND THE RISE OF CRYPTOJACKING


REMOTE HARDWARE TAKEOVER VIA VULNERABLE ADMIN SOFTWARE


THE DANGERS OF INCORRECT CSP IMPLEMENTATIONS


MOST POPULAR ARTICLES


SQL INJECTION CHEAT SHEET


HTTP SECURITY HEADERS: AN EASY WAY TO HARDEN YOUR WEB APPLICATIONS


HOW YOU CAN DISABLE DIRECTORY LISTING ON YOUR WEB SERVER – AND WHY YOU SHOULD


JSON INJECTION

Invicti Security Corp
1000 N Lamar Blvd Suite 300
Austin, TX 78703, US

© Invicti 2023

 * RESOURCES
   * Features
   * Integrations
   * Plans
   * Case Studies
   * Advisories
   * Invicti Learn
 * USE CASES
   * Penetration Testing Software
   * Website Security Scanner
   * Ethical Hacking Software
   * Web Vulnerability Scanner
   * Comparisons
   * Online Application Scanner
 * WEB SECURITY
   * The Problem with False Positives
   * Why Pay for Web Scanners
   * SQL Injection Cheat Sheet
   * Getting Started with Web Security
   * Vulnerability Index
   * Using Content Security Policy to Secure Web Applications
 * COMPANY
   * About Us
   * Contact Us
   * Support
   * Careers
   * Resources
   * Partners

© Invicti 2023
 * Legal
 * Privacy Policy
 * California Privacy Rights
 * Terms of Use
 * Accessibility
 * Sitemap

By using this website you agree with our use of cookies to improve its
performance and enhance your experience. More information in our Privacy Policy.

OK