About Hey! I'm zseano and I run BugBountyNotes. I do bugbounties full time and I managed to reach the top 10 on bugcrowd in just 8months from one program. I am lucky to attend live events by HackerOne and this is what inspired me to create this! :) I specialise in webapp testing and I love helping others. Feel free to reach out

Cross Site Scripting (XSS) - The famous alert

Before we begin, if you don't already I highly recommend checking out run by BruteLogic for great in-depth tutorials about XSS. You can always follow him aswell on

Now, let's begin. XSS is usually the most common and also the most easiest type of vulnerability to find, but what happens when WAF's and other filters are in place stopping you? Looking for XSS is simple: check every parameter. If we have GET /search.php?q=zseano, then testing the ?q= param with <script>alert(0)</script> would the first step to looking for XSS. Now we check the response and go from there. XSS is about looking for your parameters reflected in the response and tryng to inject your own HTML.

But how can we find parameters? Simple dorking and spidering can yeild you many results straight away, for example: inurl:& ext:php (change extension type to find more). Look and hunt everywhere. :)

Understanding XSS filters

So we've got the basics down with XSS so now let's discuss different scenarios of common problems that occur when testing for XSS.

Problem #1

The payload <script>alert(0)</script> is echo'd in a SCRIPT tag but is replaced to <script>alert(0)<\/script>. We can't break out of the script tag with ">, and we can't end the script tag because </script> is replaced to <\/script>. What can we do?

Things to try

Aslong as " isn't replaced to \" or %22, you should be able to use some of these payloads: "-alert(0)-", ";alert(0);//, '-alert(0)-', "+alert(0)+", ");alert(0);// Do you get the idea? Aslong as the characters " ; ) } are not filtered, you can use valid JS in order to end things like function{} and get your javascript to execute.

Problem #2

The response only contains part of the payload, for example "><script>alert(0)</script> only returns "><script>

Things to try

First things first, we know they don't filter XSS here, however this can be quite tricky to bypass as it all depends on where it is returned and if you can control anything else. I had an experience in which I was able to signup using XSS in my first and last name and whenever I commented on a post my name would render HTML set in the first name. But I was stuck to a limited number of characters so the working method was to setup three accounts with the following names:

Account one: <script>*`` << this starts a script tag and multi-comments out everything below. 
Account two: can be anything.
Account three: */</script> << this ends the multi comment tag and also the script tag!

So now, account 3 posts first (since newest comment is at top). Now account two posts the javascript to be executed by posting the following comment: / alert(0) /. Now account one comments, and in turn starts the script tag, comments out everything until it gets to my comment.. executes the "0", then comments out again until it gets to the third account which ends the script tag. There we have 3 chained payloads to achieve stored XSS and a nice payout!

Problem #3

The payload"><script>alert(0)</script> only returns "scriptalert(0)/. and strips everything else.

Things to try

We don't always need a script tag to get XSS. As long as it's reflected on a HTML tag and you can control some characters such as ' and ", as most researchers know we can use any of the following payloads: "onfocus="alert(0)" k=", "onmouseover=alert(0), "onmousenter="alert(0)" k=", etc. You can find a list of event handlers from

One common problem researchers find is when on{} is blacklisted/filtered. It all depends on where it is reflected but I find trying the payload onxss= can determine if they are filtering on*, or if just something like onfocus= is blacklisted.

For the first one I recommend trying things like on%0dmouseover= (you can also use %09, %0C, %00 here), "><b>onmouseover%3D, onmouseover=alert(0)"= (I had an experience where a WAF would allow for anything aslong as the payload ended in =). However, if it's the latter then I recommend running through the list above.

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 might just be running on a blacklist and by using things like "%0d" (for example <svg%0donload=prompt(1)>), it can sometimes confuse it, and render your XSS. Understand what the filter is looking for and start fuzzing/testing.

Here is my testing methodology when testing for XSS with the < character.

<h2> - h2 tags are usually not blacklisted
<h2 - Are they only looking for complete tags? Bypass would be <script src=//
<%00h2 - Are they looking for characters after < - can we trick it? I run through all %0d %0a etc.
</script/x> - The trailing / closing the tag can sometimes break filters

You can find a giant payload list for XSS here: