A7: Cross-Site Scripting (XSS) 2017 OWASP
We will look at what it takes to look for all kinds of XSS attacks in all sorts of contexts but also at what we can do to stop this kind of attack from one of the most damaging and varied issues from the top 10 OWASP vulnerabilities.
What Is Cross-Site Scripting (XSS)
First we need to know why this vulnerability type occurs and we can state that this issue can arise wherever the developer takes user input and renders it onto the page without sanitizing that input. There are several ways to sanitise the input of which the safest but also most restrictive seems to be whitelist based filtering.
Whitelist based filtering is implemented by checking every single piece of user content and only allowing it if that user input is defined on a whitelist. As you can see this can be very cumbersome as we need to define every single input we want to allow which can give a lot of unforeseen issues.
For those reasons a blacklist based filtering system is often chosen where the input is filtered if all or part of it occurs on a blacklist. This is a lot less safe though because if the developer forgets just 1 value on the blacklist they might be opening themselves up to major attacks.
Types of XSS attacks
We already talked a little bit about the different types of XSS but i think it helps if we go over them fully to explain the differences to you and to show you what kind of testing is expected of you as an ethical hacker because we will also be discussing the small differences in test objectives between the types of XSS.
Stored XSS takes a bit more knowledge of the program to execute successfully since you will have to test every single input field that you see. This is a GIANT task and it seems impossible but it's needed for sure. In bug bounties there will be no low hanging fruit. That will all be picked clean by pentesters already. Our amazing co-workers already did part of the work and now it's up to the bounty hunters to find that one field that everyone overlooked in their security measures.
I use the same attack vector as always and I just start. I put on some music and I register and every single input field that I see gets an attack vector thrown at it. Make sure you test everything. Look at every link on every page and actually look for hidden links as well. You can find those in JS files often because developers will put calls they are testing in the JS file and simply not call it from the production application but it's still available. This is usually a dream as we can test for things like XSS on pages that other hunters haven't even seen yet.
Blind XSS is also part of stored XSS as we try to insert an attack vector and a third party will open that attack vector via a system that we can not access under normal working conditions. This can be the back-end website of a ticketing system for example or a chat bot.
For this you need an out of band server. I use [https://xsshunter.com/](https://xsshunter.com/) You can set up your own out of band server from here. Then we need to make an attack vector that will call back to our JS script.
There are of course more payloads depending on the situation but I have a list of them.
If i can i just whack them all into a chatbot or ticketing system and hope for the best.
This is by far the most popular type of XSS out there and a lot of hunters and pentesters will focus on this as it's the easiest to test for. You don't need to know the application, all you have to do is look for reflected values which makes this vulnerability type a little bit less useful to me. I would like to get to know my application and find all the input fields that store data in the database (which would be stored XSS) but I can certainly understand the appeal here.
For reflected XSS we are going to test every single parameter by entering a random value into that parameter and seeing if it's reflected anywhere in the response. This can be the JS, the HTML, the DOM,...
When we find a reflected parameter we don't have an XSS yet. All we've found is a reflected value on our page but it might be filtered properly or sanitised. What we need to now is to see where it is reflected and craft a proper attack string for that context. For example if you are stuck in a JS context where your input is surrounded by single quotes you will have to find a way to insert your own single quote into the attack string (which will often be filtered so you have to try and get around those filters). Next you will have to craft a proper attack to either steal data or execute a function or do something useful. Remember that a popup is just a bit annoying but it has no real impact so don't just report alert(document.domain) please.
DOM based XSS
DOM XSS vulnerabilities usually arise when we can control input that is being passed into the DOM via a so-called "DOM Sources" that then gets passed into "DOM Sink" that supports dynamic code execution. Some examples can be eval() , document.write(), ...
Just like the source-based XSS we are well known with, DOM XSS also knows reflected and stored variants which obey the same rules as source-based XSS. If a variable is being reflected from a GET or a POST parameter into one of these sinks we are talking about reflected DOM XSS. If the variable comes from a value stored in the DB, we are talking about stored DOM XSS.
When we talk about DOM sinks, we talk about locations where user controlled data will enter the DOM. There are 3 types of DOM sinks and we will go over all of them.
- Document sink
In this example we are speaking to the innerHTML of an element in the DOM. This is a document sink since we are talking to an element in the document.
It's very important to note that your regular “<script>alert(1)</script>” won't work here besides several other attack vectors because this is a DOM insertion, not just a reflection of a value. When we speak of a DOM insertion. This is one of the reasons why uncle rat always tests with
Some more examples:
- Location sink
example of pseudo-protocol: (http://blabla.com/test?url=javascirpt:alert())
More examples of location sinks:
- Execution Sink
In real life you will rarely find these sinks unprotected, you will often have to bypass some test that checks if you don't enter malicious code but these checks are usually built by the developer so if there is a flaw in their logic we can bypass that check.
- DOM Source
Cross-Site Scripting (XSS) attack scenarios and examples
As for the attack scenarios we are going to discuss, we will start with a CVE that was found in August 2021, which at the writing of the article is very recent. The CVE in question is “CVE-2021-38699 TastyIgniter 3.0.7 Stored Cross Site Scripting Vulnerability”. This CVE describes a stored XSS scenario with a very deceptively easy attack vector ““><script> alert(1) </script> <script> alert(1) </script>”. This attack vector inserted into the “/account, /reservation, /admin/dashboard or /admin/system_logs” endpoints would cause a popup to appear. It might seem like a very easy to pull off but the complexity comes in finding the endpoints that have vulnerabilities in them like this.
A second example we can talk about is a stored XSS attack on a famous search engine called duckduckgo, which was found by accident. The XSS described in this disclosed report comes from the fact that duckduckgo was rendering XSS attack vectors from it’s search results which led to an XSS attack. The attack was again very simple, only requiring a payload of "><img src=x onerror=alert()> to fire. The author found this bug by searching for a XSS attack vector on urban dictionary via duckduckgo. What went on in this amazing hacker's head is anyone's guess. Both the title and description of the search results served as payloads. The full report can be found here https://hackerone.com/reports/1110229.
How XSS affects business
XSS can be a very damaging vulnerability leading to all kinds of mishaps ranging from website defacement to full account takeover of admin users. These kinds of attacks are devastating to a company and can cause at minimum a lot of reputation damage. Any damages will need to be repaired which may cause loss of data and monetary losses.
How to prevent XSS attacks
Now that we know how XSS attacks occur and what impact they can have we can follow a few key guidelines to defend ourselves from XSS attacks. These will not give full XSS protection, there is nothing that can do that.
- Make sure you have a good usage of the SOP and that you don't allow unwanted calls to other servers which are unknown.
- Make sure your CSP headers are set properly and that they do not allow for unknown domains to execute scripts on your server
- Make sure you sanitise user input. Look up how to do that in the language you are using.
- PHP: htmlspecialchars(input)
- Python: cgi.escape('malicious code here'), see: [http://docs.python.org/library/cgi.html#cgi.escape](http://docs.python.org/library/cgi.html#cgi.escape)
- aspx: [https://docs.microsoft.com/en-us/aspnet/core/security/cross-site-scripting?view=aspnetcore-5.0](https://docs.microsoft.com/en-us/aspnet/core/security/cross-site-scripting?view=aspnetcore-5.0)
- Always mark important cookies with the httpOnly flag. This will prevent any JS from accessing the values in those cookies.
While cross-site scripting may seem simple at first glance, there is a huge amount of complexity involved in the different types of XSS and in what context the attack occurs. Even after the attacks found an entry point, the real impact of XSS is broad and can require a fair bit of technical knowhow to pull off successfully.
Subscribe for the latest news