In this post, I will demonstrate different ways of XSSing or how can we XSSed a web application if user-supplied input (or input from any third-party application) reflects back as a part of any eventhandler(s) with the help of a real example(s). Please open the following URL. The harmless probe string ("xxxxxxxx'yyyyy</img) is part of URL's GET parameter i.e., searchword.
The screen-shot given below shows the reflection of our interest i.e., on*. In this particular case, the input reflects back as a part of onblur. At the same time, you will see another reflection of probe string in the screen-shot as a part of value attribute of an <input> tag. This is also a vulnerable end-point (" in use for holding the value of value attribute and " from the probe string are not filtered) but we will not discuss this.
As I mentioned in the screen-shot that developers're using " (double quote) for holding the value of onblur while ' (single quote) are in use for holding the probe string or user-supplied input. It is also clear from the screen-shot that " and ' that're part of probe string ("xxxxxxxx'yyyyy</img) are not filtered and can be seen in hard-coded form though developers're filtering everything after < sign. For us it is enough information that " and ' are not filtered. Lets start XSSing with a simple case i.e., "onmouseover="confirm(1)//. Please keep in mind that " were not filtered and the attack payload starts with " which breaks the context (i.e., two in this case: onblur and value attribute) The URL looks like the following and screen-shot shows XSS ...
Now assume double quotes (") are filtered and we can not break the context with "onmouseover="confirm(1)// so what other options do we have. Please keep in mind the reflection i.e., onblur="if(this.value=='') this.value='reflection-here';" The first potential way is ...
'; confirm(1); ' or '; confirm(1); //
The first ' from the above mentioned XSS attack payload will break the context then ; will terminate the statement (i.e., this.value). The next part of attack payload is a proof of concept JavaScript code execution via confirm(1);. The payload ends with ' that will take care of the closing ' in order to avoid syntax error or one can use single line comment (//) for neutralizing the affect of '. The screen-shot shows XSS.
The second potential way to XSS is by leveraging JavaScript's string operation(s) and the attack payload looks like ...
'-confirm(1)-'
The first ' from the above mentioned XSS attack payload will break the context then minus operator followed by a proof of concept function call (confirm(1)). In JavaScript you can subtract anything from anything and it won't care (in worst situation you will get a NaN result but never an exception) given there is a valid syntax. You can also use other operators like +, *, || and ^ etc. For the reminder, the reflection looks like onblur="if(this.value=='') this.value='reflection-here';". The this.value will carry the final value once expression on the right hand side will be evaluated and during the evaluation of expression, our payload confirm(1) is executed. The screen-shot shows XSS and the URL at this time looks like http://yaandyou.net/index.php/component/search/?searchword=%27-confirm%281%29-%27&ordering=&searchphrase=all.
Now assume both " and ' are filtered. It means that the above mentioned options for XSSing are gone. Do we still have a chance to XSS this case/particular injection point? Yes. The potential payload looks like ...
'-confirm(1)-'
Why above XSS payload works? Remember, our reflection was in eventhandler case (i.e., world of JavaScript). The browser will HTML decode the value of onblur as soon as parser reads it before proceeding (It is not only about onblur, browsers do HTML decoding of an attribute(s).). As you can see in the XSS payload, I have used the HTML5 character reference entity for ' i.e., '. The browser decoding operation will convert ' to hard-coded ' which then breaks the context (i.e., this.value='reflection-here';) and then with the help JavaScript string operation (explained some paragraphs before), XSS payload is executed. Further the decimal (i.e., ') and hex (') encoding form of ' also works respectively. The screen-shot shows XSS and the URL at this time looks like http://yaandyou.net/index.php/component/search/?searchword=%26apos;-confirm%281%29-%26apos;&ordering=&searchphrase=all
Some of you might be thinking that if ' works then why not we use the following: "onmouseover="confirm(1)// (as an alternate option to the first potential way of XSSed as I described earlier). I leave this up to you to think and figure out but in short "onmouseover="confirm(1)// does not work.
A quick search on Nerdy Data for the query "onblur="if(this.value=='') this.value=" results in more than 99K pages. Off-course all of them are not vulnerable but it will give you an idea and there is a great chance that some of them're vulnerable (e.g., after spending some time on search results I found one end-point in Alexa top 1000 sites that is vulnerable). At the same time, I found onclick landing point here. The screen-shot shows the reflection of probe string in onclick and I think they're doing good in this case.
The real life examples given above are somehow complicated cases but in the wild one can also see the following simple case related to event handlers. I found the following (see screen-shot below) as a part of WYSIWYG editor somewhere where user-supplied input directly becomes part of event handler (no involvement of any string operation). In this case, the payloads like confirm(1) or alert(1) simply works.