What is Cross-site scripting (XSS)?

Cross-site scripting (XSS) is a web security vulnerability in which an attacker is able to inject malicious scripts into vulnerable sites and compromise the interaction between the user and the site. Cross-site scripting is what we call a “client side” attack malicious code is executed within the user’s browser and can be used to gain unauthorised access to user accounts or carry out actions while impersonating a user.

If an attacker is able to trigger a Cross-site scripting attack against a privileged account, it may be possible to achieve a complete compromise of an application and it’s data.

Want to learn all about XSS Vulnerabilities?

You can download a free PDF lesson with working examples.

But how does it work?

To understand Cross-site scripting, it is important to understand the fundamental workings of web applications. At its core, a web application functions as a bridge between a user and a server. When you interact with a web application, your browser sends a request to a server, this is processed and the appropriate page/data is returned and displayed in your browser. This relies on trust, the trust that the data received is safe and came from the server hosting the website.
Cross-site scripting exploits this trust. Applications use a mixture of HTML, CSS, and JavaScript to provide the look, feel, and functionality of their sites. When attackers are able to manipulate an application into returning malicious JavaScript, it is possible to trigger the execution of a specific action that will occur in your browser. This is made possible when applications fail to properly validate and sanitise user input.

An effective XSS methodology

To conduct an effective test for XSS, a methodical approach can be taken that will give you the knowledge needed to successfully execute XSS attacks against even the most sophisticated of applications.

This guide will walk you through the steps needed to be able to identify and exploit XSS vulnerabilities.

  1. Investigate parameters: Explore all the parameters available and look at the source code to understand what you are injecting into
  2. Check filtering: Test what HTML and JavaScript tags are accepted
  3. Create a proof of concept: Use this knowledge to create a PoC and demonstrate that XSS can be achieved
  4. Weaponise your payload: Now is the time to take your working payload and modify it to achieve your goal

Reflected Cross-Site Scripting

Reflected XSS can be triggered when a user submits data during an HTTP request and this data is included in the HTTP response. In essence the data is “reflected” back to the user. This can occur in web functionality such as search results, error messages, or any other input that is displayed in the response.

Reflected XSS is typically triggered by URL parameters containing malicious JavaScript. As such, to use this form of XSS against a target user, there is a requirement of some form of social engineering. There needs to be some method to convince a user to send the HTTP request with the malicious code to the server. This can be achieved by providing malicious links for users to follow.

Stored Cross-site scripting

Stored XSS can be triggered when an application accepts data from a user and includes this data within later HTTP responses. In essence, the data is “stored” on the server ready for a user to request a page that hold the malicious JavaScript. This can occur in web functionality such as forum comments, usernames, contact details etc. Anywhere where user data is stored and embedded in later responses

Stored XSS is much more damaging than reflected XSS due to the method of distribution to the victim. There is no need to get a victim to follow a link, instead stored XSS is saved to a web page, then an attacker waits for users to visit the page and trigger the malicious code.

DOM XSS

First, DOM stands for Document Object Model, a fundamental concept of web development. It is an API for web documents. When a page is loaded, the browser creates a Document Object Model of that page, this model allows developers to manipulate the structure, style, and content with JavaScript.
Unlike other forms of XSS, because the DOM is within a user’s browser, DOM XSS does not rely on server responses. Instead, it directly manipulates how web pages are rendered in a user’s browser.

function displayMessage() {
var userMessage = window.location.hash.substring(1);
var messageContainer = document.getElementById('message-container');
messageContainer.innerHTML = 'Welcome, ' + userMessage + '!';
}

In the above code, the JavaScript function displayMessage() retrieves the value (userMessage) from a URL that follows the # (userMessage = window.location.hash.substring(1);)

This value is inserted into the DOM using messageContainer.innerHTML, this could be used to render a custom welcome message to each user. If an attacker is able to control the input value, it would be possible to trigger XSS

But how do we test for it?

There are some basic XSS payloads that are commonly used as proof of concept payloads. These are payloads that, if executed, visually demonstrate the existence of an XSS vulnerability. These may use the following functions:

alert()
confirm()
print()

alert() / confirm()

Now there are a huge number of potential XSS payloads that bring a lot of complexity and value. But the above alert() and confirm() payloads are commonly used by testers to trigger an dialog box displayed in the browser

print()

When vulnerable parameters exist in cross-domain iframes, visual Proof of Concepts such as alert() no longer work. In these instances using the print() function can provide the visual confirmation that an payload has executed.

Want to continue learning about XSS Vulnerabilities?

You can download a free PDF lesson with working examples.