Sunday, November 15, 2015

JavaScript's Built-In Function(s) --- A Potential XSS Venue

This post shows how developers (not all of them) are using JavaScript's built-in functions in the wild and how we can leverage them for XSS given user-supplied input reflects as a part of these functions. I will demonstrate XSS by giving four real examples in the wild. Though four examples can never ever be a representative of the whole web but at least it will give an idea. 

decodeURI

According to MDN, decodeURI decodes encoded URI (i.e., URI encoded form). Lets see it on a real site in the wild. Please open the following URL (topic GET parameter holds our probe string i.e., "xxxxxxxx'yyyyy</img): The News.Cn is a popular Chinese site and at the time of writing its global Alexa rank is 3420. 


The reflection that is of our interest (part of decodeURI function) can be seen in the following screen-shot. The developers are using single quote for holding the user-supplied input while single quote as a part of probe string reflects back in its hard coded form. The < from the probe string has been converted into its HTML encoded form i.e., &lt; Isn't decodeURI expects URI encoded form? In this case, this seems missing. 


We have the following potential choices for XSSing in this case.

  • </script><script>confirm(1)</script> 
  • '-confirm(1)-' or '-confirm`1`-'
  • Respect the Syntax 

The case where we prematurely closes the script block (i.e., </script><script>confirm(1)</script>) is no more an option in this particular example because < is converted into &lt; In case of '-confirm(1)-' (In JavaScript you can subtract anything from anything and it won't care), the URL looks like the following at the time of XSS.

http://t.home.news.cn/spIndex.action?ds=all&h=458&pageSize=20&temp=topicRoll&topic='-confirm(1)-'

The respect the syntax case also works and in this case, please make sure to take care of characters like single quote, parenthesis and semi-colon etc by keeping in mind the given syntax. If you remember the reflection in decodeURI, it looks like ...

var topic =  decodeURI('reflection here');

There are potentially two options by looking at the syntax above. I will mark the injections in red for your convenience. In both cases given below, the payloads start with ' to break the context and after ', there is ) which makes sure to properly close the decodeURI function (i.e., it would be a decodeURI function call with an empty string). The next part of XSS payloads is ; which is a statement terminator. This will close the var declarations. The next thing/item is a proof of concept function call of confirm(1) along with statement terminator i.e., confirm(1);. If you will stop here and tries to execute the payloads, you will get an uncaught syntax error on the console because of ');. At this point, again we have two options i.e., (' or // (single line comment) respectively in order to avoid syntax error. The single line comments (//) can neutralizes or normalizes the affect of ');     

var topic =  decodeURI('');confirm(1);(''); 
var topic =  decodeURI('');confirm(1);//');

The URLs look like the following at the time of XSSing by keeping in mind respect the syntax cases.



The screen-shot shows XSS in all potentially possible ways. 



replace (JavaScript String replace Method)

According to MDN, replace method returns a string after a pattern (string or regular expression) or characters' replacement. Lets see it on a real site in the wild. Please open the following URL (including our probe string i.e., "xxxxxxxx'yyyyy</img): The Zaobao is a popular site in Singapore.


The reflection that is of our interest (part of replace function) can be seen in the following screen-shot. The developers are using double quote for holding the user-supplied input in the replace function while double quote as a part of probe string reflects back in its hard coded form. The </ from the probe string can also be seen in its hard-coded form. The game is over here.


The URLs at the time of XSSing look like (choice is yours) ...

http://www.zaobao.com.sg/search/site/");confirm(1);// (does not work because // is filtered)

Here is the screen-shot of XSS.


window.location.replace

According to MDN, location.replace method replaces the location of the current resource or document with the one provided in its argument. Lets see it on a real site in the wild. Please open the following URL (q GET parameter holds our probe string i.e., "xxxxxxxx'yyyyy</img): The global Alexa rank of Bloomberg is 295.


The reflection that is of our interest (part of window.location.replace function) can be seen in the following screen-shot. The developers are using single quote for holding the user-supplied input in the window.location.replace function while single quote as a part of probe string reflects back in its hard coded form. The </ from the probe string can also be seen in its hard-coded form. The game is over here.


I will show only one potential way for XSS but will leave others for you to explore or take as an exercise. The URL at the time of XSSing looks like the following.


Here is the screen-shot.



I found another example in the wild where reflection occurs in window.location.replace. Please open the URL in Firefox browser. You can easily figure out other potential ways of executing arbitrary JavaScript code that work across browsers e.g., '-confirm(1)-'.

http://app.medyanetads.com/redir.a2?URL=</script><script>confirm(1);</script>&ciid=457810&tid=13674

Here is the screen-shot.


Note: In case you have found an XSS in similar cases as given above, please feel free to share. Along with the above mentioned functions, I had also seen parseInt() and document.location.replace() in the wild. Thanks!


2 comments:

Note: Only a member of this blog may post a comment.