FAST TRACK
See our Fast Start promotion and start your first pentest on The Cobalt Offensive Security Testing Platform for only $4,950.
FAST TRACK
See our Fast Start promotion and start your first pentest on The Cobalt Offensive Security Testing Platform for only $4,950.

Testing for Reflective XSS - Part 2

In the previous blog about Reflective XSS, we discussed how to manually test for XSS in HTML tags and attributes, along with their bypasses. In this second part, we will explore how to exploit XSS when input is reflected in JavaScript code, for example, when the user input is reflected inside a <script> tag or an event handler.

What is <script> tag?

A <script> tag in HTML is a way to include and run JavaScript code on a webpage. You use the <script> tag to either write JavaScript code directly or link to an external JavaScript file. When the browser loads the webpage, it finds the <script> tag and executes the JavaScript code.

Examples: Inline JavaScript

<!DOCTYPE html>
<html>
<head>
    <title>Example Page</title>
</head>
<body>
    <h1>Hello, World!</h1>
    <script>
        alert('This is an inline JavaScript code!');
    </script>
</body>
</html>

 

External JavaScript

<!DOCTYPE html>
<html>
<head>
    <title>Example Page</title>
    <script src="script.js"></script>
</head>
<body>
    <h1>Hello, World!</h1>
</body>
</html>

In the first example, the JavaScript code runs directly from within the HTML file. In the second example, the JavaScript code is in an external file called script.js, and the <script> tag links to that file.

How Browsers Parse and Render HTML and JavaScript


1. HTML Parsing:

  • The browser reads the HTML file from top to bottom.
  • It builds a structure called the Document Object Model (DOM), which represents the elements on the page.

2. CSS Parsing

  • If the HTML file includes CSS (Cascading Style Sheets), the browser reads and applies the styles.

3. JavaScript Execution

  • When the browser encounters a <script> tag, it pauses HTML parsing to load and execute JavaScript.
  • If the <script> tag includes src, the browser fetches the external JavaScript file and runs it.

4. Rendering

  • After parsing HTML, CSS, and executing JavaScript, the browser combines the DOM and CSSOM to render the webpage visually.

Possible Reflection points inside <script> tag

Reflection points in <script> tags are places where user input can be dynamically inserted into JavaScript code. Here are some common reflection points within <script> tags:

1. Inline JavaScript

  • This script assigns the value USER_INPUT to the variable userInput and then logs it to the browser's console. If USER_INPUT is derived from user input and contains malicious JavaScript, it could lead to cross-site scripting (XSS).

2. Dynamic Script Content

<script>
    var message = "Welcome, " + "USER_INPUT";
    alert(message);
</script>
  • In this script, a message is dynamically created by concatenating the string Welcome, with USER_INPUT. The resulting message is then displayed in an alert box. If USER_INPUT is untrusted user input, it could include harmful script content, leading to an XSS attack.

3. DOM

<script>
    document.getElementById("username").innerHTML = "USER_INPUT";
</script>
  • This script targets an HTML element with the ID username and replaces its inner HTML with the value of "USER_INPUT". If "USER_INPUT" contains malicious content, it could alter the webpage's structure or behavior, leading to XSS vulnerabilities.

4. Event Handlers

<script>
    document.getElementById("myButton").onclick = function() {
        alert("Hello, " + "USER_INPUT");
    };
</script>
  • Here, an event handler is assigned to an HTML element with the ID myButton. When the button is clicked, an alert box displays a message that includes "USER_INPUT". If "USER_INPUT" is unsafe and is not properly sanitized, it could trigger XSS when the event is fired.

5. URL Parameters

<script>
    var params = new URLSearchParams(window.location.search);
    var user = params.get('user');   // USER_INPUT
    document.write("Hello, " + user);
</script>
  • This script extracts the user parameter from the URL's query string and uses it to write a greeting directly into the document. If the user parameter contains unsensitized input, it could lead to XSS by executing malicious scripts directly in the user's browser.

How to break out of JavaScript syntax?

Now, let’s try to break the context between the <script> tags using the example.

Input: https://example.com/?search=fuzz

Reflected Output:

Screenshot 2024-09-13 at 2.51.46 PM

Here, in this case, we have two reflection points: one between <h1> tags and another between <script> tags. So now, let's try to break the content in Reflection 1 by adding a < character, just like we learned in Part 1.

Input: https://example.com/?search=fuzz<>

Reflected Output:

Screenshot 2024-09-13 at 2.53.25 PM

In the above image, you can see that the application is encoding the inputs and converting the < character to &lt; and the > character to &gt; in both of the reflection points here. This means we cannot perform XSS in Reflection 1. 

Let’s move on to Reflection 2 now. The syntax is JavaScript here, so we need to insert a payload that breaks the context and triggers the alert. First, the application is using a single quote here. Let’s try inserting a single quote (') to break the context.

Input: https://example.com/?search=fuzz<>’

Reflected Output:

Screenshot 2024-09-13 at 2.54.24 PM

Here, you can analyze Reflection 2 and observe that the application does not sanitize the ' character. Now, let’s attempt to perform XSS here. In JavaScript, you can insert a string using two hyphens (-). Therefore, our payload would be -alert(1)- in this context.

Input: https://example.com/?search=fuzz<>’-alert(1)-’

Reflected Output:

Screenshot 2024-09-13 at 2.55.06 PMIn Reflection 2 you can see that the color of syntax has been changed and it is a valid JavaScript syntax.

var searchTerms = 'fuzz&lt;&gt;'-alert(1)-'';

Breakdown of the Code

  1. 'fuzz&lt;&gt;' 
  • This is a string that contains the HTML entities &lt; and &gt;
  • &lt; stands for the less-than symbol (<).
  • &gt; stands for the greater-than symbol (>).
  • So, 'fuzz&lt;&gt;' is equivalent to the string 'fuzz<>', where the < and > characters are encoded in HTML entity form.
  1. '-alert(1)-'
  • This part is a string that seems to be intended as an XSS payload or test input. It contains the JavaScript function alert(1) surrounded by hyphens.
  • The alert(1) function would, if executed in a browser, display a popup alert box with the number "1".

testingxss1

Final Thoughts

When testing for XSS, you should avoid spamming multiple payloads. Instead, try enumerating what is being blocked or sanitized by the application and find alternatives to bypass the restrictions.

Citations: Portswigger

SANS Application & API Security Survey 2024 CTA

Back to Blog
About Meet Sodha
Meet aka Smilehacker is a seasoned cybersecurity researcher with an impressive four-year track record in the field. His journey began in 2019 when he delved into the world of bug bounties and application security, rapidly honing his skills and expertise. Meet possesses a profound understanding of application security and continually augments his knowledge by devouring articles, engaging in hands-on labs, and conducting extensive research in specialized areas. With a keen eye for vulnerabilities and a passion for safeguarding digital landscapes, Meet is a trusted guardian of online security, dedicated to staying one step ahead of cyber threats. More By Meet Sodha
A Pentester’s Guide to Cross-Site Scripting (XSS)
Examine a common security vulnerability, Cross-Site Scripting (XSS).
Blog
Oct 30, 2020
2022 Pentester Spotlight Recaps
With 2023 just around the corner, we wanted to reflect on our Pentester Spotlights from this year. Our Pentester Spotlight series is focused on highlighting the Cobalt Core Pentesters and putting a face to their work
Blog
Dec 30, 2022