Find and Exploit Cross Site Scripting (XSS) Flaws

How to Find and Exploit Cross Site Scripting (XSS) Vulnerabilities

In a previous post, How to Prevent Cross Site Scripting, I explain how to prevent Cross Site Scripting (XSS) issues. This article will demonstrate a simple approach how to identify and exploit cross site scripting vulnerabilities.

Meet our target..

I am using an old version of Blog Engine .Net , released in 2008. If you are still using 5+ year old open source blogging software without upgrading, well you might want to stop reading this and upgrade to the latest version, which is currently at 2.9.

The first step in detecting any Cross Site Scripting (XSS) vulnerability is to do a reflection analysis. What is a reflection analysis? I’m glad you asked! Cross Site Scripting (XSS) is characterized by displaying back, or reflecting, user supplied data. So if we submit a string of data to the web application, and that string of data is returned back to us in the rendered page it means our data might be able to impact the structure of the rendered page if not properly handled.

So what data do we submit to an application to test if we can impact the rendered document object module (DOM)? There are various test strings you can use and there is a lengthy list of strings to bypass cross site scripting (XSS) filters provided here. When I test applications for cross site scripting (XSS) vulnerabilities I will use a string that captures what field I entered the data into, a number string that shouldn’t be encoded (for simple searching later), and then a number of characters I am interested in determining will be escaped or not, (i.e. [NameOfField]123456789”%”*+,-/;<=>^|). Testing like this is usually done with an intercepting proxy such as Portswigger’s Burp Suite, but for this demonstration we will add the injection string directly into the form and skip the fields we can’t directly interact with for now.

After submitting this post, we will investigate the returned page to see where our data ended up (if anywhere) and if our characters were escaped or not. The test string I put into the “slug” field actually broke the page navigation (opps!).

Once I was able to navigate to the rendered posts I noticed that there was some strange text where the “Email” option once was. “Thought you might like this”? How fitting. That exactly what I wanted to see! I had influence of the way the page was rendered! Hooray! The people rejoice! Let’s investigate the HTML source to see what we did.

Remember I added a number string, i.e. “12356789” to my injected data? Well this is why, easy searching!

Upon investigation we can see that my “less than” and “greater than” signs have been encoded in a number of areas. These are the characters most people will associated with cross site scripting (XSS). If those characters are not allowed, then cross site scripting must not be possible! Not quite. If we take a look at line 16, we can see that the injected double quote character actually terminated the HTML tag’s attribute field and the rest of the characters were rendered outside of it. Firefox, like most browsers, did its best to understand the poor syntax of the HTML page and rendered it as best it could. We can alter the HTML DOM with a double quote! Huzzah! Let’s make it do something interesting!

Our injection string is: TestTitle” onmouseover=”alert(“xss”);”. “TestTitle” is just dummy data. The first double quote will close out the anchor tag’s href attribute. Next we add the JavaScript event handler “onmouseover” which will execute JavaScript when the anchor tag is hovered over. Let test it!

We got code execution! We found and exploited a cross site scripting vulnerability! That was fun but, how do we prevent this from happening? In a previous post, How to Prevent Cross Site Scripting, I explain how to prevent cross site scripting. The core fix for this is to properly encode data before being displayed back to the user. This is usually done by a built in, non-security-aware HTMLEncode() method. My next article will demonstrate why HTMLEncode() is not appropriate encoding data placed into an HTML tag’s attribute field.

Recommended Reading

[amazon template=iframe image&chan=default&asin=1597491543 ][amazon template=iframe image&chan=default&asin=159749951X ][amazon template=iframe image&chan=default&asin=1118026470 ]