Test your knowledge with BugBountyHunter Challenges


Resources

A list of useful websites, blog posts, reports tools to help you.

Learning about Cross Site Scripting (XSS)


XSS (known as Cross Site Scripting) is usually the most common and also the most easiest type of vulnerability to find since you are simply looking for your input reflected in the response. What do we mean by this?

Imagine this: You are currently on the website URL https://www.example.com/login?return=/home. You notice ?return=/home and from checking the source via view-source:https://www.example.com/login?return=/home you confirm /home is reflected as, <script>var return = '/home';</script>. If you change return to /test and notice it's changed then you've confirmed you can control it. You can simply check every parameter & look for your input in the response.

You're looking for parameters that are reflected that you can control

Next, we need to see if it's actually vulnerable to XSS. We can control the reflection, but we need to cause some impact which means executing our own HTML/JS. An example: If we used a payload such as </script><svg/onload=alert(0)> and your payload is reflected as valid HTML then it should show a popup box with "0". This type of vulnerability is called reflective xss. The web application is handling your inputted value and reflecting it on the source.

Dont be mistaken and just use Inspect Element when looking for your reflection. Inspect Element will open the DOM, whereas view-source will open the raw HTML. What's the difference? Imagine this:, when viewing /user/settings, one application will simply reflect your information, which can be found in both inspect element and view-source:. But, another web application makes another request to /api/user/settings and appends the response in the DOM. You won't see your information via view-source, but you will via Inspect Element. This is because the data was retrieved from elsewhere and appended. Use both approaches when checking for your reflection.

That's not all with XSS as there are different types. Imagine this: you can signup to your website and you give yourself a display name of <svg/onload=alert(0)> and the website allows you to share posts on your page (like twitter). When posting you notice an "0" javascript alert box. This would be Stored XSS as the web application has stored your input and it's reflected without you needing to use any parameters in the GET/POST request. In the first example we inputted it via the parameter, ?return=, but in this case we saved and stored the input first and then web application reflected it for us.

Those are two examples of XSS and how you are simply looking for your value being reflected as valid HTML. With that said, not every XSS is as straight forward as that as sometimes filters/WAFs are in place to prevent XSS attacks and certain characters are restricted. Let's first explore each XSS type and some scenarios you may discover these.

Different types of XSS

Input everywhere

Input xss payloads where-ever possible. Your name, in your email (test+<h2>@test.com), bio. See how it's handled and reflected, is anything stripped/filtered? Don't use the most common <script> as most web applications will filter this and instead start with something "harmless" such as <h2>. This is more likely to work especially if some type of html markdown rendering is being used and you can work on building an XSS payload with impact. Carry on reading to learn more on the flow of testing for XSS.

Discovering parameters

Apart from looking in your web proxy logs for ?parameter= when navigating the web application and seeing the parameters being used are simply right there in front of you you can also discover more by looking in the raw html (view-source:) and the DOM (Inspect element) for things such as <input id='param1' name='param1'> and begin building a wordlist to fuzz. For example in this case you'd try param1 as a parameter. You can also browse .js files (look for var =) or you can simply brute force commonly known parameter names, such as returnUrl.

I can not stress enough how much large companies re-use code & parameter names across lots of endpoints.

Testing XSS and if there's any filters

Here is my simple testing methodology when testing for XSS. Each case will help you determine what's being filtered

<h2> vs <script> - h2 tags are usually not blacklisted. how are both handled?

<script src=//evil/?c= - Are they only looking for complete tags? Notice we don't end the HTML tag and append extra HTML as a parameter!

</script/x> - The trailing / closing the tag can sometimes break filters. I have high success rate with this.

<<h2>> - may strip the outter < > leaving <h2>

<IFRAME> - is it case sensitive?

"onxss= - are they only looking for the most known on{} event handlers? onxss= isn't valid. Does it error when using onerror= but not when onxss=?

Using the above will give you a clear indication if something is vulnerable to XSS as well as information on what they may be filtering. Now imagine you've determined <h2> is reflected, but <script> is not, this means we're faced with a filter. We know it's vulnerable to XSS as it reflects our innocent <h2> tag, but they're filtering malicious html tags.

Understanding XSS filters

Firstly, if no matter what payload you use, you always see &lt;script&gt;, %3Cscript%3E then it is not likely to be vulnerable. However, developers like to try introduce filters for various reasons which create XSS opportunities. Instead of preventing HTML payloads altogether via correct sanitisation/encoding, they choose to filter out "malicious" html. Filters can be good sometimes in a way as it means you get to play & try to reverse enigneer the developers thoughts. From understanding how a developer has chosen to filter certain XSS payloads, it can give you an idea for the security throughout (perhaps similar filtering exists on a potential SSRF?). Below are some common cases when testing XSS and how I go about trying to create a working proof of concept (PoC).


Beating WAFs

The last peice of advice i'd like to give researchers faced with a filter/waf when hunting for XSS is to remember the WAF is typically just looking for certain strings. It might even be running on a blacklist and by using things like "%0d" (for example <svg%0donload=prompt(1)>), it can sometimes bypass it and render your XSS. Understand what the filter is looking for and start fuzzing/testing. I've noticed java%09script: will bypass CloudFlare WAF in certain cases.

Creating impact

Sometimes bug bounty programs will reward more if a proof of concept is provided with your XSS, rather than using alert(0). Some examples for creating impact can be seen below.