Practical Example of Escaping XSS Context

whatminjacodes [she/they] - Sep 30 - - Dev Community

In this post, I’ll show an example of a reflected XSS vulnerability where the user input is reflected inside a JavaScript context.

Understanding Context in Cross-Site Scripting (XSS)

In Cross-Site Scripting (XSS), context refers to two main factors, according to Portswigger:

  • The location where user-controlled data is reflected on the web page.
  • Any input validation or processing applied to that data by the web application.

The idea is that by identifying where the data appears on the page (its context), you can determine how to escape from that specific context and inject JavaScript code to, for example, prompt an alert box. Triggering an alert box is a common technique used to demonstrate a Proof of Concept (PoC) for an XSS vulnerability on a webpage.

What is "Escaping" in XSS?

In XSS attacks, escaping refers to the technique of breaking out of a given context to execute malicious code. For example, if user input is reflected inside an HTML attribute, you can attempt to break out of that attribute and insert executable JavaScript code. The goal is to inject code in a way that alters the structure of the existing web page or script, allowing you to control what gets executed.

By understanding how input is handled in the web application, you can figure out which characters are needed to break out of the context (like closing a tag) and where to inject your malicious script.

Different XSS Contexts

XSS can occur in various contexts, such as inside HTML elements, attributes, or JavaScript code blocks. To discover XSS vulnerabilities, it's important to understand how the data is handled within the application and how to break out of that context to inject executable scripts.

The method for escaping depends on where the input is reflected:

  • HTML Tag Attribute Context: Your input is placed inside an HTML attribute (e.g., value="user input"). To escape from this, you might need to close the attribute value, close the tag, and introduce a new one.
  • HTML tags: Your input is placed inside an HTML tags (e.g., <div>user input</div>). When the XSS context is text between HTML tags, you might need to introduce some new HTML tags designed to trigger execution of JavaScript.
  • JavaScript Context: Your input is reflected inside a JavaScript block (e.g., var data = 'user input';). When the XSS context involves existing JavaScript in the response, various scenarios can occur, each requiring specific techniques to successfully exploit the vulnerability.

The method for escaping depends on where the input is reflected, which is why understanding the context is crucial for exploiting XSS.

Practical Example of Escaping XSS Context

This example is based on PortSwigger's lab called "Reflected XSS into a JavaScript string with single quote and backslash escaped" but it's similar to an XSS vulnerability I discovered during a security assessment. You can also open the lab and test this yourself if you want to!

After opening the lab, we see a webpage that has a search bar on it. When we search for "TestInput" on the search bar, we get "0 search results for 'TestInput'" as a result. After doing a search, you can right-click on the page and choose "Inspect" (on Firefox) to search if the input we send is reflected on the code of the page.

Screenshot of the webpage showing the reflected input

In this case, we notice the "TestInput" is indeed reflected and we can see it is inside <script> tags:

<script>
    var searchTerms = 'TestInput';
    document.write('<img src="/resources/images/tracker.gif?searchTerms='+encodeURIComponent(searchTerms)+'">');
</script>
Enter fullscreen mode Exit fullscreen mode

We can then try what happens by sending <script>alert("Test")</script> on the search bar:

Screenshot of the webpage showing the reflected input

We notice that the end part of the previous <script> block is now visible on the UI and that inside the <script> block is now the following:

<script>
    var searchTerms = '<script>alert("Test")
</script>
Enter fullscreen mode Exit fullscreen mode

As the rest of the code block is now out of the <script> tag, we can determine that we were able to close the <script> tag early and the rest of the code is then shown on the UI.

Let's try closing the <script> tag first like this </script><script>alert("Test")</script> and then call the script for triggering an alert box:

Screenshot of the webpage showing the triggered alert box

As you can see from the screenshot above, the escape was successful and we were able to trigger the alert box!

Btw, you can also achieve this same result by adding the </script><script>alert("Test")</script> on the URL and sending the request like that:

Screenshot showing the added JavaScript in the URL

That's it!

I wrote this blog post to demonstrate that it's possible to find these "simple" XSS vulnerabilities in real-world services. I also want to remind you that working through lab examples is not pointless! I’ve sometimes felt that way myself, especially since the lab environments are often designed to be intentionally vulnerable. But these exercises really do help build the skills needed for real-world testing.

Background

As an Information Security Specialist at 2NS, I get to learn something new about cybersecurity every day. Through this blog, I aim to share insights, tools, and techniques that I find valuable in my work, hoping to help others in the field.

Follow me on Instagram @whatminjahacks for a behind-the-scenes look at my work as an ethical hacker, and to learn more cybersecurity tips and insights!

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .