Cross-Site Scripting (XSS)
In this chapter, we are going to learn about cross-site scripting (or also called XSS).
Type of vulnerability: Client-Side
Chances to find: Very high; XSS is ranked #3 in the “OWASP Top-10 Vulnerabilities“
TL;DR: An XSS vulnerability allows an attacker to execute Javascript code in the browser of a victim. This enables an adversary to fully compromise the victim’s account by e.g. performing any action on the website that the user could perform as well.
What is cross-site scripting?
Cross-Site Scripting (XSS) attacks are a type of injection, in which malicious scripts are injected into otherwise benign and trusted websites. XSS attacks occur when an attacker uses a web application to send malicious code, generally in the form of a browser side script, to a different end-user. (src: OWASP)
Before we are diving deeper into the variations of XSS, let’s have a quick look at an example, how an XSS exploit looks like:
Example of an XSS payload triggering an XSS vulnerability
High-level overview of different XSS classes
Click on the links below to receive in-depth knowledge about every category.
Reflected Cross-Site Scripting – XSS payload is delivered inside the HTTP request sent to the server and displayed immediately.
Stored Cross-Site Scripting – XSS payload is stored on the target server (e.g. in a database) and is delivered via the HTTP response.
DOM-based Cross-Site Scripting – XSS payload is entirely handled inside the browser (triggered by a sensitive and vulnerable method).
Reflected cross-site scripting
Reflected XSS is occurring if user input is sent to the server within an HTTP request, which is then immediately printed out on the website in an insecure fashion.
A classic example would be a URL, which contains a parameter that can be altered by a user, where the input is mirrored and made visible.
Example URL: https://example.com/?user=Intigriti
Example output:
<span id="user">
<b>Hi Intigriti</b>
</span>
If the underlying code responsible for creating the server response is not performing any type of sanitization and if the output is not properly encoded, an attacker could try to send a malicious request.
Malicious example URL: https://example.com/?user=%3Cscript%3Ealert(document.domain)%3C/script%3E
This would result in the following output:
<span id="user">
<b>Hi <script>alert(document.domain)</script></b>
</span>
If an attacker would craft such a malicious example and send it to his victim, the victim would see an alert box popping up displaying the website’s domain. The attacker would need an additional trick to make the victim click on the URL (such as a phishing email).
Recommended Write-Ups:
admin.google.com Reflected Cross-Site Scripting (XSS) (by Brett Buerhaus)
From Reflected XSS to Account Takeover — Showing XSS Impact (by Abugzlife)
Stored cross-site scripting
Stored XSS is occurring if a malicious Javascript payload, that has been previously stored on a system, is requested and delivered in an HTTP response by a victim at a later point in time.
Web applications offer a very diverse set of functionalities these days. A lot of them enable a user to store information that they would want to share with somebody else (e.g. think of social media platforms, the comment section on news websites, a forum, and many more).
Whenever a user sends in information for later use, the application needs to store that data somewhere (typically in a database). If stored information is then displayed to a victim in an insecure fashion, an attacker can make us of that.
Example URL: https://example.com/forum/thread/1?content=this%20is%20a%20test
Example output:
<span id="content">
<b>This is a test</b>
</span>
If the underlying code responsible for creating the server response is not performing any type of sanitization and if the output is not properly encoded, an attacker could try to send a malicious request.
Malicious example URL: https://example.com/forum/thread/1?content=%3Cscript%3Eprint()%3C/script%3E
This would result in the following output:
<span id="content">
<b><script>print()</script></b>
</span>
If an attacker would craft such a malicious example and send it to his victim, the victim would see a print window popping up within the browser. The attacker would need an additional trick to make the victim click on the URL (such as a phishing email).
Recommended Write-Ups:
DOM-based cross-site scripting
DOM-based XSS is occurring when client-side Javascript (running in the browser) is processing data coming from various sources in an insecure fashion, writing the malicious output in the DOM (document object model).
Example URL: https://example.com/?username=Intigriti
Example script running on the website (where a script reads the username provided within the URL):
<script>
let username=document.URL.indexOf("username=")+9;
let usernamePlaceholder=document.getElementById('usernamePlaceholder');
usernamePlaceholder='Hi there, '+username;
</script>
This would result in the following output:
<span id="username">
<b>Hi there, Intigriti</b>
</span>
If the script running inside the browser is not performing any type of sanitization and if the output is not properly encoded, an attacker could try to send a malicious request.
Malicious example URL: https://example.com/?username=%3Cscript%3Edocument.write(%22test%22)%3C/script%3E
This would result in the following output:
<span id="username">
<b>Hi there, <script>document.write("test")</script></b>
</span>
If an attacker would craft such a malicious example and send it to his victim, the victim would see a an empty blank page containing the string “test”. The attacker would need an additional trick to make the victim click on the URL (such as a phishing email).
Recommended Write-Ups:
Reflected DOM XSS and CLICKJACKING on https://silvergoldbull.de/bt.html (by Daniel Maksimovic)
Impact
Until now, we have only seen XSS payloads that are rather benign if a victim falls for them. What could an attacker potentially achieve by maliciously misusing an XSS vulnerability:
Install a key-logger to read every single button press on a given domain (e.g. to spy on a user’s password)
Act on the behalf of the victim on the website (e.g. post messages, update information)
Retrieve confidential data that is supposed to be only visible to the victim (e.g. PII data)
Change the website’s appearance in order to trick the victim into performing further unwanted actions
etc.
Further variants of cross-site scripting
Blind cross-site scripting
Blind XSS occurs when user input is stored in a in place that cannot be visited by an attacker. Given that situation, it’s hard to confirm that a vulnerability exists since the attacker doesn’t have access to the page where the payload might trigger (hence the word “blind”). A basic example would be a contact form, where you are able to send a message to employees of a company. While you can send payloads, you don’t know how the malicious input is going to be processed on the backend.
In order to help to get feedback for blind XSS attacks, you can use tools such as XSSHunter, which send a callback to a domain of your choice. Watch this video to learn how to set up XSSHunter.
Recommended write-ups:
Self-XSS
Self-XSS occurs when user input gets printed out to the web app in an insecure way, while you can only exploit the XSS vulnerability against yourself, or if you convince the victim to paste Javascript code in the browser’s console (which is considered phishing). As self-XSS findings are typically not in the scope of bug bounty programs, it is better to try chaining the vulnerability with an additional attack vector.
Recommended write-ups:
Time to practice!
Intigriti is continuously releasing new XSS challenges on our Twitter account. Make sure to participate in order to win swag and to show the world your skills!
Example of a previous XSS challenge:
Additional external challenges:
How to prevent cross-site scripting?
A short summary of the XSS prevention cheat sheet by OWASP:
Never Insert Untrusted Data Except in Allowed Locations
HTML Escape Before Inserting Untrusted Data into HTML Element Content
Attribute Escape Before Inserting Untrusted Data into HTML Common Attributes
JavaScript Escape Before Inserting Untrusted Data into JavaScript Data Values
CSS Escape And Strictly Validate Before Inserting Untrusted Data into HTML Style Property Values
URL Escape Before Inserting Untrusted Data into HTML URL Parameter Values
Sanitize HTML Markup with a Library Designed for the Job
Avoid JavaScript URL’s