Challenge 11: XSS CSP bypass through an inline script
Learn how a misconfigured CSP can be bypassed, potentially leading to the successful exploitation of cross-site scripting vulnerability.
Welcome to learning XSS with the Kurukshetra Series.
Before getting started, ensure your Kurukshetra lab is up and running. Feel free to refer back to the below link.
XSS Challenge Walk-Through
Once your Kurukshetra XSS lab environment is up and running, Visit http://localhost:8066 and navigate to “XSS Challenge 11“.
- Click and select the XSS Challenge 11 from the Kurukshetra app.
- Fill out our classic XSS payload in the given input field.
- Click on the “Submit” button.
Output:
4. The application loads the page as usual and displays a text message, "Your XSS Payload" without any pop-ups.
5. Right-click and select “View page source“, then search for the injected XSS payload. The HTML response code will be displayed below.
6. At the bottom of the HTML response, the payload was injected as provided and also aligned rightly with the HTML syntax. But our javascript didn't execute.
What might be happening in the background?
In the above screenshot, if the HTML output encoding is used, then the output must be displayed as “<” or “>” etc. Doesn’t look so. Also, if slash-escape is being used, then the prefix slashes must be displayed. Even that is not present.
Seems like our XSS payload is injected rightly but unable to execute. A possible guess is there is some sort of other XSS defense in place.
The web application might have enabled the Content Security Policy or other XSS protection headers. Let’s verify and understand what's happening in the background.
On the following XSS challenge page, Press the “F12” button on your keyboard and a new browser debugger window will be launched.
In browser debugger mode navigate to “Console” and observe the CSP violation messages will be displayed as shown below.
Web Browser clearly indicates some script code tried to execute but it's not compliant with the CSP policy set. Therefore it was blocked by the browser from executing.
In debugger mode, switch to "Network" and reload the challenge page.
Select the "ch11.php" page and observe on the right side in "Response Headers" the Content-Security-Policy header, which was set by the web application.
Understanding the CSP implementation
Breaking down the CSP policy defined by the web application
- script-src: specifies the sources from which scripts can be loaded.
- https://facebook.com: allows scripts to be loaded from the domain facebook.com.
- https://google.com: allows scripts to be loaded from the domain google.com.
- unsafe-eval: This allows the eval() javascript function and the Function() constructor to execute dynamically created script code.
- "data:": allows the execution of inline scripts (one which is directly embedded in the HTML) with data URIs.
- "http://*": Wildcard "*" means allows scripts to be loaded from any HTTP sources (poses a security risk).
2. child-src: specifies the sources from which nested browsing contexts (such as iframes or embedded objects) can be loaded. In this case, 'none' specifies that no sources are allowed.
3. report-uri: specifies the URL where a browser should send violation reports if the policy is breached.
Overall, this CSP allows scripts to be loaded from trusted domains (facebook.com and google.com), as well as inline scripts and HTTP sources (which are generally not recommended due to security risks). It also allows the use of eval()
and Function()
, which can be used to exploit XSS attacks. Additionally, it prohibits the loading of nested browsing contexts and specifies a URL to which violation reports should be sent.
The above CSP policy clearly has some limitations and is not foolproof. That said, "data:" provided an entryway for us to try creating XSS inline scripts or load the XSS script code from any of the HTTP domains, tricking the application by loading from Google, etc.
Exploiting XSS using Inline scripts
(i.e., using data directive)
Let's go ahead and find a way to bypass the misconfigured CSP defenses. For the following demonstrations, we will be using the script-src's "data:" attribute to craft an XSS payload.
From the documentation script source "data:" can be used for inserting inline scripts directly into HTML documents.
The "data:" URI scheme allows data to be embedded directly in a URL or document, using a specific syntax that includes the "data:" prefix followed by the MIME type of the data, and the data itself.
Below is an XSS inline script using the "data:" URI scheme, which can be included directly, with the MIME type set to "text/javascript" and an "alert('xss')" data.
Above code will pop up with an "XSS" message when the javascript code is loaded and executed directly on the page.
Visit the "XSS challenge 11" page.
Enter the XSS inline script code in the input field and click on the "Submit" button.
Output:
Immediately, we can see a pop-up message displayed on the web page. By this, we can confirm that we have successfully exploited the XSS vulnerability. :D
To further confirm, click on the "OK" message, then right-click and select "View page source". Search for the injected XSS inline script code.
HTML Page Source:
Observe this time, our injected script code is reflected back as given without any output being filtered.
The execution script code confirms we have successfully solved the XSS challenge 11. Yayy!!!.
Use of the "data:" URI scheme for inline scripts can be problematic from a security perspective, as it allows arbitrary code to be executed directly on the page, which is generally abused by attackers to perform cross-site scripting (XSS) attacks.
Summary
A Content Security Policy (CSP) policy restricts the types of content that can be loaded by a web page. When implemented correctly, a CSP can prevent cross-site scripting (XSS) attacks by limiting the sources from which scripts can be loaded.
However, if a CSP policy is misconfigured or contains errors, it can potentially allow XSS attacks to occur. For example, if a policy includes insecure sources, such as "unsafe-inline" or "data:", it can enable attackers to inject malicious scripts directly into a web page, potentially leading to XSS attacks.
Therefore, a well-configured CSP policy can block all XSS attacks, and it is important to ensure that CSP policies are correctly configured and free from insecure directives.