Showing posts with label Encoding. Show all posts
Showing posts with label Encoding. Show all posts

Sunday, January 10, 2016

When Reflected Becomes Stored

In this post, I will discuss an interesting case of XSS i.e., when a classical reflected XSS becomes stored XSS. The transition from reflected to stored happens because developers convert user-supplied input into some form of encoding, make it part of a URL and permanently store it in the database. I was thinking why developers do this at first place? The apparent reason, I can think of from the top of my head is tracking or for analytic purpose e.g., popular searches. If you know any other reason, please let me know. At the same time, I think, this type of practice makes the exploitation easy i.e., an attacker may hide the payload as a part of legit URL. Vishal Sharma in his blog-post also points out that cloud-based WAF can be bypassable with the help of this feature of web application because WAF never sees the harmful payload unless decode.    

Lets see this with two real life examples from the wild. On the following URL: http://www.akc.org/, if you will enter a letter `a` in the main search bar and hit enter. The site will give you a URL that looks like: http://www.akc.org/search/YQ/. Now if you will query for the letter `b` in the search feature then site will ends up on a URL like: http://www.akc.org/search/Yg/. You may continue to see the behavior of web application on different inputs and may try to figure out the type of encoding in place. Lets input our harmless probe string "xxxxxxxx'yyyyy</img and as a result the site will give you a URL: http://www.akc.org/search/Inh4eHh4eHh4J3l5eXl5PC9pbWc/. The source code inspection shows the reflection of our interest in the following screen-shot.  


The screen-shot shows the probe string reflects back as a part of JavaScript's built-in function i.e., encodeURIComponent. The developers're using single quote (') for holding the value of function and it can be seen that single quote (') from the probe string ("xxxxxxxx'yyyyy</img) is not filtered or encoded. I already did a write-up on reflections in JavaScript's built-in functions. The XSSing in this case is not difficult. The payload '-confirm(1)-' does the job. The URL at the time of XSSing looks like: http://www.akc.org/search/Jy1jb25maXJtKDEpLSc/ and the screen-shot is also given below.


Now see another example in the wild (sorry for hiding the URL). The screen-shot shows the reflection of probe string but if you will see the value of SysSearch GET parameter, you will find some sort of encoding in the URL instead of hard-coded probe string ("xxxxxxxx'yyyyy</img). The screen-shot also show that < is not encoded in an HTML context. The game is over for them given < is not filtered or encoded in an HTML context.


The next screen-shot shows XSS with the help of simple and popular payload i.e., <img src=x onerror=confirm(1)>. The payload does not start with ' or " quotes because we're in HTML context. Please look at the value of SysSearch GET parameter. It is not hard-coded XSS payload but you will find encoded form.


If as a developer you still wants to use this type of feature then please make sure to follow the basic , well known and million dollar principle of "Filter Input,  Encode Output".
     

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 http://www.businessinsider.com.au/?s=%3Cimg%20src=x%20onerror=confirm%281%29;%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 http://www.autos.ca/ 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.