Recently, one of my friends asked me about my methodology while looking for Cross-Site Scripting, so I decided to do a blog post on it.

Here, I will not be going over the different types of XSS vulnerabilities, its impact and all those things, and my assumption is that you already know and understand what it is, so, let's get started.

When I am trying to look for vulnerabilities in any web app, apart from constantly moving from the Proxy tab to the Repeater tab in Burp, I usually think about the things that I would have missed if I was the one writing the code. And this approach really helps to understand what is going on and, think of possible vulnerabilities. Recalling my time as a developer, I don't really remember me sanitizing user input all the time, most of the times, I relied on the built in functions, the framework and the easy ways, because well, let's face it, I was lazy and had a lot of code to write. Security just wasn't a priority during that time. However, now, security is the priority. And, sometimes when I test out the old web apps that I created... well, I don't have words for it, its just embarrassing.
Okay, I feel like this looks long enough for an introduction. Let's move on to the good stuff.

Now, although firing all the XSS payloads and polyglots present in SecLists might sound like a plan for many, that is not really the best way to do it. You usually won't understand what's happening and how you were able to exploit it. That would kinda be the script kiddie way of doing it.

Here, I'd like to suggest another approach, and I'm sure some of you are already doing it this way. Or, if you have a different approach, and want to share it, feel fry to contact me about it.

Before we move on, it is important to find out if there is a WAF protecting the Web App. If there is one, we should try to identify it and see if there are any valid payloads that can be used to bypass these WAFs.
To find and identify the presence of a WAF, you can use wafw00f.

Step 1: Finding Reflections

Here, the topic really explains itself. We are trying to find a reflection of our input data, either in the same page or a different one.
You can use some super random and unique string which you can easily search for in the response HTML. For example: abhizerasjkalf123498d.
I usually dump it everywhere and if I find that it is reflected, I try to figure out which input caused it.

Step 2: Checking for the presence of Filters and Encoding

Now, once I find the inputs that are getting reflected, I try to test out the filters, check what gets filtered or encoded. To do this, I drop in all kinds of special characters.
'"/\<>+=%$_-!@#()*&^~|}{?
Also, I try some things like %00 which is a null character.
I try to come up with a list of characters that aren't filtered.
While trying this out, I also try to check if it is possible to bypass the filtering by URL encoding the payload, double encoding or, base64 or similar things. The end goal here, is to come up with a list of characters that don't get filtered or, try to bypass some filtered characters to be able to use those previously filtered characters as well.

Step 3: Coming up with a Payload

Finally, once we have identified the characters that aren't encoded, we can try to come up with a payload, depending upon our specific case to try and exploit the possible XSS vulnerability. Depending upon where your input is reflected, you will need to craft your payload.
For example, if it is reflected within an attribute inside a tag, your goal should be to exit that attribute and create some other attribute like, onload=alert(1) so that once it loads, the XSS fires. However, this highly depends upon the case.

And, if none of these work, sometimes, I try throwing in polyglots and XSS payloads, but by this time, I will have an understanding of the filtering and can encode it accordingly to try to bypass the filter and exploit the XSS vulnerability.

Additional Tips:

Now, once you've found an XSS vulnerability, there are different ways to exploit it. Launching a popup box is one way but not the only way. You can try defacing the website, changing the background color or doing something similar. Or, if you want to take it further, you can attach a BeEF hook.
Usually, finding an XSS gives the attacker a chance to chain it and make it a much larger vulnerability. You could try to steal cookies, bypass CSRF protections and similar things.

If you liked this article, feel free to share it with others and if you want to talk about something or share your approach, hit me up on Twitter @the_abhizer or, email me at: abhizer@abhizer.com