Friday, December 25, 2015

A Hardcore XSS

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','&quot;xxx&#39;yy&lt;/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.

Lets see different potential ways to XSS this case. The developers're using ' for holding the function parameters and single quote is not filtered. It is enough of information for us. The first method is simple/straight-forward and the XSS attack payload will be '-confirm(1)-'. The URL at the time of XSS is:'-confirm%281%29-'/sortierung/Datum followed by a screen-shot.

The next potential way to XSS this case is with the help of &apos;-confirm(1)-&apos;. The URL at this time looks like:;-confirm%281%29-&apos;/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 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)-', &apos;-confirm(1)-&apos; 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 (&apos;-confirm(1)-&apos;) 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: &apos;-confirm(1)-&apos; and thanks to browser's HTML decoding &apos; 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.

Sunday, December 20, 2015

Is Escaping an Option There?

In the real example cases, you will see in this post, escaping SHOULD NOT be the option ... please go for encoding. I found many instances of the following types of reflections in the wild where one SHOULD NOT use escaping but unfortunately it is there. Please open the following URL (Inquirer has a global Alexa rank of 1049 at the time of writing). The GET parameter q holds our probe string "xxxxxxxx'yyyyy</img

The screen-shot shows the reflection in an attribute context (i.e., value attribute of an <input> tag) and you will see that " and ' from the probe string are escaped i.e., \" and \' respectively. At the same time, </ is not controlled. 

In an attribute context, escaping is not a good choice. The developers're using " for the holding the value of value attribute and at the same time, they escaped " i.e., \". The developers think that they are done and it is not possible to break the context. Lets see one potential way (there are many) to XSS this. The XSS attack payload looks like "onmouseover=confirm(1)//. The URL at the time of XSSing is followed by screen-shot:

In the source code, the <input> tag looks like:

<input type="text" name="q" value="\"onmouseover=confirm(1)//" autocomplete="off" />

The more interesting thing is if you look at the innerHTML of the above mentioned <input> tag. This would give better picture why above mentioned XSS attack vector works given " are escaped in an attribute context. I used Live DOM Viewer made by Ian Hixie for this purpose. The innerHTML looks like ...

<input type="text" name="q" value="\" onmouseover="confirm(1)//&quot;" autocomplete="off">

For you to see and test it yourself, the short exercise would be why the following XSS attack payloads do not work? "onmouseover="confirm(1) and "onmouseover="confirm(1)//. Now we see another reflection where escaping SHOULD NOT be there but it is. Please open the following URL (BusinessInsider has a global Alexa rank of 7393 at the time of writing). The GET parameter s holds our probe string "xxxxxxxx'yyyyy</img.

The screen-shot shows the reflection of probe string in an HTML context (<h3> opening and closing tag is around reflection of probe string) and you will see that " and ' from the probe string are escaped i.e., \" and \' respectively. At the same time, </ is not controlled. In an HTML context, if < is not controlled (filtered or encoded) then game is over 99% of the time.

The URL at the time of XSSing looks like;%3E followed by a screen-shot. This XSS is now fixed.

I was thinking what could be the reason of escaping " and ' in an attribute and HTML context? I think because of single XSS protection applied on a web application in general or they're using one XSS protection for all cases (escaping is good in script context e.g., JavaScript String Literal Case). The sad thing is that I found many instances of escaping in an attribute and HTML context in the wild. It is a common mistake. The context-specific case(s) was not in the mind.  If you can think of any other reason(s), please feel free to share as part of comment section below. At the same time, if you have a reason or justification that escaping can be applied in above mentioned cases (i.e., attribute and HTML context), then I would be very happy to see the real example(s) where it is working fine.

Update: Ouch ... Forward Slash for Escaping

Recently, I found a real life case where developers're using forward slash (/) for escaping double (") and single quotes (') respectively in an HTML context. As I said earlier in the post that escaping is not an option in an HTML and attribute context and at the same time, developers're using instead of \. The can be used as an escaper in an script context. Please open the following URL and input XSS probe string "xxxxxxxx'yyyyy</img in the main search bar. The screen-shot given below shows the reflection.

The URL at the time of XSSing is given below followed by a screen-shot. The XSS in this case is very simple because </ is not filtered or encoded in an HTML context.

Sunday, December 13, 2015

No Quotes At All

In this post, I will describe a rare variation of common reflection points. We all know and have seen reflection in JavaScript string literal case and <input> tag's having type attribute set to hidden i.e.,

var any-variable-name="reflection here"; // double quoted case
var any-variable-name='reflection here'; // single quoted case


<input type="hidden" value="reflection here"> // double quoted case
<input type='hidden' value='reflection here'// single quoted case

In the wild, developers either use single (') or double (") quote for JavaScript string literals and the same holds true for <input> tag. But how often you see a reflection without any quotes at all in the wild (though as per W3C specification it is allowed)? I mean something like that ...

var any-variable-name=reflection here; // no quotes at all


<input type=hidden value=reflection here// no quotes at all

I think it is a needle in a haystack. I found real examples (one I am sharing here and one I can't) of such reflection without any quotes so I thought it would be interesting to share. Please open the following URL (GET parameter rp holds our harmless XSS probe string "xxxxxxxx'yyyyy</img). The site NEWS.CN has an Alexa rank of 3573 at the time of writing.

The screen-shot shows the reflection of our interest. In the screen-shot you can see the probe string ("xxxxxxxx'yyyyy</img) reflects back as a part of rp JavaScript variable and the developers're not using any quotes. 

So how to XSS this case? It would be very simple. The proof of concept XSS payloads like confirm(1), alert(1) and prompt(1) etc simply works. The URL at the time of XSS looks like the following and the screen-shot is also given.

The same page has another reflection (without quotes) as a part of <input> tag's hidden value and it is shown in the following screen-shot.

It can be easily XSSed and there are many ways. The URL at the time of XSS looks like the following and the screen-shot is also given. The XSS payload starts with a space character (i.e., %20). Why? I leave this up to you to figure out. It's easy.

Sunday, December 6, 2015

The Dark Side of Comments

Comments are good. We all know and have a general consensus on that. The developers should make use of comments in a useful manner. One more aspect of comment that normally we see in the wild is: developers often comment out unwanted or unused code. This may be because the functionality (code) is no more needed or there can be any other reason. This is where the problem starts. Lets elaborate it with the help of real examples from Alexa top sites. Please open the following URL (our harmless probe string "xxxxxxxx'yyyyy</img is part of URL's GET parameter slowo) and the following screen-shot shows the reflection of our interest (i.e., inside an HTML comment block). The site GAZETA has an Alexa rank of 589 at the time of writing.

It can be seen in the screen-shot above that our XSS probe string (i.e., "xxxxxxxx'yyyyy</img) lands as a part of value of <input> tag's value attribute in particular while there're HTML comments  (<!-- -->) around the <input> tag. Further " from the probe string has been encoded into &quot; while < is not filtered. In my experience, if < is not filtered than 99.9% of the time > is also not controlled but will get back to it later. Now for the moment, imagine that HTML comments are not there around the <input> tag then is it possible to break the context (i.e., attribute context)? In order to break the attribute context (i.e., value attribute of an <input> tag), we need hard-coded " because developers're using it. The " are properly encoded into &quot; so no chance to break the context in modern browsers.

Now lets see how we can leverage HTML comments that're around <input> tag and < is not filtered as can be seen in the screen-shot above. The implicit assumption is that > is also not filtered. Lets inject the following XSS attack payload -->anyxssattackvectorhere. The goal is to prematurely closes the HTML comment block and then execute JavaScript with the help of any XSS attack vector. The browsers are good guys and as soon as the parser detects the syntax/token -->, it will try its level best to close the HTML comment even though reflection was part of quoted attribute (i.e., value attribute of an <input> tag). Please remember for the browser's parser, HTML comment has already been started (i.e., <!--) before the <input> tag. The URL at the time of XSS looks like the following and screen-shot is also given below:


The next example related to HTML comments is from one of the Alexa top 500 sites. Please open the following URL (YAOLAN's Alexa rank at the time of writing is 399). The probe string "xxxxxxxx'yyyyy</img is part of URL's GET parameter searchWord.

The following screen-shot shows the reflection in HTML comments which is of our interest. There are other reflections (can be XSSed) also on the page but we will not consider them.

It is clear from the reflection of XSS probe string that " has been filtered (removed) while < is there in its hard-coded form. The developers are using " for the value attribute of <input> tag and " has been filtered so it means that in this particular reflection or case, we can not break the context (i.e., attribute context) in modern browsers. Further, reflection shows that < is not filtered so the assumption that > is also not filtered should work while at the same time please keep in mind that we want to prematurely close the HTML comment block. The attack payload will be looks like -->anyxssattackvectorhere. The URL at the time of XSS should looks like the following.

I was expecting a confirm box having 1 but got the following Chinese message (available in the form of screen-shot). I think some sort of malicious code detection mechanism (may be some WAF) was in place on their site (I translated the message and realized).

Now this would be interesting :) After spending few minutes on their detection, I realized the following (go and test yourself for fun):
  • <iframe>, <object>, <meta>, <style> and <script> tags are part of their black-list
  • <svg>, <img>, <details> and <p> tags works
  • onerror=confirm(1) does not work and it has been detected
  • onerror%0a=%0aconfirm(1) becomes onerror%0a=%0aconfirm1 (small parenthesis are removed) // It means not detected ... but () has been removed
  • ontoggle=confirm(1) becomes ontoggle=confirm1
  • javascript: has been detected but javascript&colon; works
  • `` was not removed so we can use confirm`1` instead of confirm(1)
  • many more .... 
I think it is enough. Lets XSSed it. The URL at the time of XSS looks like the following and the screen-shot is also given below.><p/id=1%0Aonmousemove%0A=%0Aconfirm`1`>

I deliberately picked a XSS vector that needs user-interaction so that you can identify and see yourself the vulnerable end-point i.e., inside comment block. On the page, there are other vulnerable end-points also. I found some real examples related to JavaScript comments and how can we leverage them for XSS but I will write about JavaScript comments later sometime. I will conclude on ... Why not delete the unwanted or unused code instead of commenting out?