What is cross-site scripting (XSS)?
Cross-site scripting, commonly referred to as XSS, is a web security vulnerability that allows an attacker to compromise how a user interacts with a vulnerable application. It allows an attacker to circumvent the ‘same-origin’ policy, which is designed to segregate different websites from each other. Typically, cross-site scripting vulnerabilities will allow an attacker to act as a victim user which they then abuse to perform actions or access data that the user should be able to do. This means that if the victim user has elevated permissions as an administrator of the application, then the attacker might be able to gain complete control over all of the application – including it’s sensitive data.
How does XSS work?
Cross-site scripting occurs when a vulnerable application or web site is manipulated so that malicious scripts (JavaScript) is returned to users. Once that malicious script is executed in a user/victim’s browser, the nefarious actor can fully compromise that user’s interaction with the application.
What are the types of XSS attacks?
There are three main types of XSS attacks. These are:
- Reflected Cross-Site Scripting: Malicious script comes from the HTTP request.
- Stored Cross-Site Scripting: Malicious script comes from the database of the web application.
- DOM-based Cross-Site Scripting: Malicious script comes from client-side code instead of server-side code.
— Reflected XSS
Reflected XSS is the most common variety of cross-site scripting. It occurs when an application receives data in a HTTP request and that request includes data within the immediate response in an insecure way.
Here is a simple example of a reflected XSS vulnerability:
https://unprotected-website.com/status?message=All+is+well. <p>Status: All is well.</p>
The application doesn’t correctly handle or process the input, so an attacker can easily construct an attack like this:
https://insecure-website.com/status?message=<script>/*+scary+stuff+here...+*/</script> <p>Status: <script>/* Scary stuff here... */</script></p>
If an unknowing user visits the URL constructed by the nefarious actor, then the attacker’s script will execute in the victim’s browser. At that point, because the application doesn’t properly process the input, the script can carry out any action that the user has the permissions to do. This could be used to retrieve data that only the victim should have access to, but the malicious script will provide that info to the attacker.
— Stored XSS
Stored XSS, which is commonly called persistent or second-order XSS, occurs when an application receives data from an untrusted source and then actually includes that data within its HTTP responses in an insecure way.
The information or data might be submitted to the application via HTTP requests. As an example, let’s say that a forum lets users submit messages to other users.
<p>Hello, this is my message!</p>
If the application doesn’t perform any other processing of the user input, an attacker can easily send a message that targets other users by submitting malicious payloads. For an example..
<p><script>/* scary stuff here... */</script></p>
— DOM XSS
DOM XSS occurs when an application contains JavaScript on the client-side that processes data from an untrusted source in an insecure way.
In the example below, an application uses JavaScript to read the input and then writes that value to an element within the HTML:
var search = document.getElementById('search').value; var results = document.getElementById('results'); results.innerHTML = 'You searched for: ' + search;
If the attacker can control the value of the input field, then they can just as easily construct a malicious input that causes their own script to execute:
You searched for: <img src=1 onerror='/* scary stuff here... */'>
Typically, the input field would be populated from part of the HTTP request, (such as a URL query string) which would allow the attacker to deliver an attack using a malicious URL in the same way as reflected XSS (which we discussed above).
What can XSS be used for?
A nefarious actor who leverages a cross-site scripting vulnerability might be able to accomplish a number of different things:
- Impersonate the user that unknowingly executed the attackers script.
- Perform any actions that the victim is allowed to.
- Access all data that the victim can access.
- Compromise the victim’s login credentials.
Impact of XSS vulnerabilities
As with many vulnerabilities, the impact of cross-site scripting can vary in a number of ways. This is why it’s important to perform penetration tests on web applications so that you can determine what the business impact of any given vulnerability is.
The impact strongly relies on variables such as the type of data an application has, the permissions that the victim has, and the general functionality of the application. If you reference the ‘What can XSS be used for?” section above, you can imagine the impact if a banking application was to be vulnerable to XSS. Conversely the impact may not be as severe if a website advertising a local party is vulnerable.
How to prevent XSS attacks
It’s difficult to cover all the different ways to prevent cross-site scripting vulnerabilities in a single article, let alone a single paragraph. For a comprehensive review of preventing XSS, we’d recommend going through the cheat sheet that OWASP put together. Below are some general rules to follow:
- Education and awareness: Ensure that developers have knowledge of common security vulnerabilities and risks found in web applications. Security should be baked into the software development life cycle (SDLC) and OWASP vulnerabilities should be front of mind for developers.
- Sanitize Input: When user input is received, you should filter as strictly as possible based on what type of input is expected. Overall, you should never trust user input.
- Content Security Policy: CSP can be used to define what domains are trusted to run executable scripts. When correctly configured, this can theoretically mitigate XXS as an attack vector.