The traditional way to prove that you’ve found a cross-site scripting vulnerability is to create a popup using the alert() function. This isn’t because XSS has anything to do with popups; it’s simply a way to prove that you can execute arbitrary JavaScript on a given domain. You might notice some people using alert(document.domain)
. This is a way of making it explicit which domain the JavaScript is executing on | Karthikeyan Nagaraj
Exploiting cross-site scripting vulnerabilities
The traditional way to prove that you’ve found a cross-site scripting vulnerability is to create a popup using the alert() function. This isn’t because XSS has anything to do with popups; it’s simply a way to prove that you can execute arbitrary JavaScript on a given domain. You might notice some people using alert(document.domain)
. This is a way of making it explicit which domain the JavaScript is executing on.
Sometimes you’ll want to go further and prove that an XSS vulnerability is a real threat by providing a full exploit. In this section, we’ll explore three of the most popular and powerful ways to exploit an XSS vulnerability.
Exploiting cross-site scripting to steal cookies
Stealing cookies is a traditional way to exploit XSS. Most web applications use cookies for session handling. You can exploit cross-site scripting vulnerabilities to send the victim’s cookies to your own domain, then manually inject the cookies into the browser and impersonate the victim.
In practice, this approach has some significant limitations:
- The victim might not be logged in.
- Many applications hide their cookies from JavaScript using the
HttpOnly
flag.
- Sessions might be locked to additional factors like the user’s IP address.
- The session might time out before you’re able to hijack it.
Exploiting cross-site scripting to capture passwords
These days, many users have password managers that auto-fill their passwords. You can take advantage of this by creating a password input, reading out the auto-filled password, and sending it to your own domain. This technique avoids most of the problems associated with stealing cookies, and can even gain access to every other account where the victim has reused the same password.
The primary disadvantage of this technique is that it only works on users who have a password manager that performs password auto-fill. (Of course, if a user doesn’t have a password saved you can still attempt to obtain their password through an on-site phishing attack, but it’s not quite the same.)
Exploiting cross-site scripting to perform CSRF
Anything a legitimate user can do on a web site, you can probably do too with XSS. Depending on the site you’re targeting, you might be able to make a victim send a message, accept a friend request, commit a backdoor to a source code repository, or transfer some Bitcoin.
Some websites allow logged-in users to change their email address without re-entering their password. If you’ve found an XSS vulnerability, you can make it trigger this functionality to change the victim’s email address to one that you control, and then trigger a password reset to gain access to the account.
This type of exploit is typically referred to as cross-site request forgery (CSRF), which is slightly confusing because CSRF can also occur as a standalone vulnerability. When CSRF occurs as a standalone vulnerability, it can be patched using strategies like anti-CSRF tokens. However, these strategies do not provide any protection if an XSS vulnerability is also present.
Exploiting DOM XSS with different sources and sinks
In principle, a website is vulnerable to DOM-based cross-site scripting if there is an executable path via which data can propagate from source to sink. In practice, different sources and sinks have differing properties and behavior that can affect exploitability, and determine what techniques are necessary. Additionally, the website’s scripts might perform validation or other processing of data that must be accommodated when attempting to exploit a vulnerability. There are a variety of sinks that are relevant to DOM-based vulnerabilities. Please refer to the list below for details.
The document.write sink works with script elements, so you can use a simple payload, such as the one below:
document.write('... <script>alert(document.domain)</script> ...');
Note, however, that in some situations the content that is written to document.write includes some surrounding context that you need to take account of in your exploit. For example, you might need to close some existing elements before using your JavaScript payload.
If a framework like AngularJS is used, it may be possible to execute JavaScript without angle brackets or events. When a site uses the ng-app attribute on an HTML element, it will be processed by AngularJS. In this case, AngularJS will execute JavaScript inside double curly braces that can occur directly in HTML or inside attributes.
DOM XSS combined with reflected and stored data
Some pure DOM-based vulnerabilities are self-contained within a single page. If a script reads some data from the URL and writes it to a dangerous sink, then the vulnerability is entirely client-side.
However, sources aren’t limited to data that is directly exposed by browsers — they can also originate from the website. For example, websites often reflect URL parameters in the HTML response from the server. This is commonly associated with normal XSS, but it can also lead to reflected DOM XSS vulnerabilities.
In a reflected DOM XSS vulnerability, the server processes data from the request, and echoes the data into the response. The reflected data might be placed into a JavaScript string literal, or a data item within the DOM, such as a form field. A script on the page then processes the reflected data in an unsafe way, ultimately writing it to a dangerous sink.
eval('var data = "reflected string"');
Websites may also store data on the server and reflect it elsewhere. In a stored DOM XSS vulnerability, the server receives data from one request, stores it, and then includes the data in a later response. A script within the later response contains a sink which then processes the data in an unsafe way.
element.innerHTML = comment.author
Thank you for Reading!
Happy Ethical Hacking ~
Author: Karthikeyan Nagaraj ~ Cyberw1ng