Merry Christmas to you all...
Tim Willis of Chrome security team called it `hardcore-one` in his talk available here. Alexis Imperial-Legrand (ail) from Google security team already did a good and generalized write-up here. I would call it a `trickier` XSS in both ways i.e., finding and fixing. I have always been interested in finding this XSS in the wild and found many instances of it on popular sites (including a popular proprietary CMS). I will not unveil the name of CMS at the moment but will see later sometime. I also found this hardcore/trickier XSS in SAP Enterprise or NetWeaver Portal.
Some days ago, I asked a question i.e., Is <a href="javascript:go('a','"xxx'yy</i');">X</a> it a good XSS protection or not given ', " and <> are encoded? I asked the question on Twitter and poll result shows 30% have given the wrong answer while 70% were correct (total votes casted were 70). This post is intended for the 30% while 70% know everything and they can skip reading this post and continue safe and happy browsing :) Lets see real life example from the wild. Please open the following URL ...
In order to keep it simple for better understanding, I initially used the word "reflection-here". The screen-shot shows the reflection of our interest (i.e., function call within a JavaScript URI).
Now see the same reflection but this time our harmless probe string ("xxxxxxxx'yyyyy</img) will be part of it. It shows that ' from our probe string is not filtered or encoded while " and < are URL encoded.
The next potential way to XSS this case is with the help of '-confirm(1)-'. The URL at this time looks like: http://www.nordbayern.de/portalsuche/suchbegriff/'-confirm%281%29-'/sortierung/Datum and the screen-shot is also given.
Why it works? I will come into it later but first lets see another potential way of XSSing this case. I will now use another real life example (inject payload in main search bar on this URL http://www.kyobobook.co.kr/search/SearchCommonMain.jsp) from the wild. It would be great if someone will figure out why I am using new example for this. Please spend sometime on the URL and you will find out why the following attack payload does not work on the URL mentioned earlier. The next attack payload is: %27-confirm(1)-%27 and the screen-shot is also given.
In short, so far we have seen three different ways i.e., '-confirm(1)-', '-confirm(1)-' and %27-confirm(1)-%27. The first way ('-confirm(1)-') is simple and straightforward because single quote was not filtered as can be seen in the probe string reflection while in the second ('-confirm(1)-') and third (%27-confirm(1)-%27) method, there is an involvement of browsers' decoding as far as XSS is concerned. If you will go through Tim Willis's talk, one of the slide was about browsers' decoding. The slide from Tim Willis's given below shows how browsers' decoding order work ...
As I said earlier that the second potential way to XSS this case was: '-confirm(1)-' and thanks to browser's HTML decoding ' becomes hard-coded single quote (') which subsequently breaks the context and via JavaScript string operation, it gets executed. In the third potential way (%27-confirm(1)-%27) for XSSing this case, there is nothing related to HTML decoding but this time URL decoding plays its rule and %27 becomes hard-coded single quote ('). This XSS is more trickier especially if you want to apply a fix. Alexis Imperial-Legrand (ail) had already explained in his post the correct escaping order ...
- JavaScript Escaping
- URL Percent Encoding
- HTML Escaping
Before jump to the conclusion, there is still one more potential way for XSSing this special case. Imagine if " are not filtered or encoded. If you will look at the first screen-shot on this page, you will find that developers're using " for holding the value of href attribute. In case " are not encoded then you can use a payload like "onmouseover="confirm(1). The following screen-shot shows the payload in action. The screen-shot is from another web site because " are encoded in case of earlier mentioned web applications.
In short, we have seen all potential ways to XSS this case and at the same time, now you have some real examples to play with.