I apologize ahead of time if I start to ramble through this post.  Script injections are major vulnerability in web applications due to the variety of attacks that can result from one injection point and there’s a lot we can talk about.  If we take a look at the Verizon Data Breach Investigation Report, we see the Cross-Site Scripting was involved in 6.3% of web application data breaches last year.  This number is obviously higher in industries that have a higher number over web app data breaches, such as the financial services or information sectors.  But if you’re new to the cyber security/penetration testing field, these will be the bane of your existence.  No matter how many times you describe remediation techniques to your development teams, they will always find a way to let a couple of well-designed scripts through.  The WhiteHat Website Security Statistics Report shows that 47% of applications are vulnerable to Cross-Site Scripting, making it the third most common form of vulnerability behind information leakage (56%) and insufficient transport layer protection (70%).  Before I bore you with any more statistics, let’s dive into some fun testing methods.

I’ll be honest, if you and your team utilize an automated scanner, it will do the majority of the work for you.  Most of the scanners that I’ve used a highly reliable in identifying injection points (AppScan and Burp Suite Scanner are great, OWASP ZAP is ehh).  But that doesn’t mean you can’t make some fun proof-of-concepts for your report.  Let’s start with the basics, but feel free to skip ahead if this is old news.  I follow a couple of steps when doing my testing:

  1. Identify the reflected parameter
    1. Where is it reflected? (example: is it reflected in the HTML or in a JavaScript block)
  2. Analyze any type of input validation
    1. What symbols are rejected/stripped/encoded?
    2. Are certain tags rejected?
    3. Will it reject action events?
    4. Are regular expressions used to strip certain content?
  3. Trial and Error
    1. How do we bypass any restrictions?
    2. How do we build on our base injection?

All of the examples I’m going to show were tested on IBM AppScan’s test site which can be found here.  If you want to reproduce any of the tests or do you own tests, it’s a great site to experiment with.

Identifying Reflected Parameters

Some parameters will be obvious when they’re reflected, and some will be completely hidden.  Over time and with more experience you’ll start to learn where to look.  In our test site, there is a parameter that is clearly reflected back into the response when using the search feature:


Pretty hard to miss that.  Now that we’ve identified a parameter, we can start trying to identify if there’s any protection already in place (Spoiler alert: there isn’t).  So let’s try to inject the most basic of all script injections alert(1):


So what happened here?  The content of the parameter was reflected back into the response.  Since the content contained a valid script, it was processed by the browser as valid JavaScript and executed:


This is just a very basic example.  The reflected content can appear in several other places such as the value of an input tag or even in a block of JavaScript.  It’s important to recognize where your targeted parameter is being reflected and be mindful of the different methods of creating a valid script.  Always have the mind set of an attacker.  Let’s move on.

Analyzing Input Validation

The name of the game is trial and error.  Burp Suite’s Repeater will be your best friend, and Intruder can do some of the heavy lifting.  I’d recommend familiarizing yourself with these tools, and I plan on covering Burp Suite in a separate post (there’s just SO much functionality to cover).  The key is to think like the development team.  What is happening on the back end to stop you from injecting your script?  Let’s go through some examples of poor input validation and how to dodge them.

Note: In these examples, we are assuming that the validation solution is application wide.  There are some cases where there may be different methods of validating input across different parts of the application.  This is far from ideal, and it would be worth noting to the development team.

Example 1: Tag Blacklisting

So you’re a developer and you ask yourself, “How do I stop these attackers from injecting scripts?”  Your first thought might be to block all script tags.  Seems like a good idea, but we can work around this pretty easily.  There are plenty of other HTML tags that we can use to execute JavaScript such as iFrames, links, and even marquees.  Let’s try this with an iFrame tag by injecting <iframe src=javascript:alert(1)>:


Pretty simple work around.  All we did was set the source of the iFrame to a JavaScript action and it executed.  We can even do this with a marquee, using the injection <marquee onstart=alert(1)>test</marquee>:


This is a similar situation.  We gave the marquee tag an action event (onstart) which will execute the JavaScript.  I think at this point it’s obvious that blacklisting tags is not an ideal solution.  It’s unreliable to attempt to block every tag.

Example 2: Stripping Using Regular Expressions

This is similar to the previous example.  The solution will use regular expressions to match malicious patterns, and then strip the matches out of the response.  For example, the regular expression below will match JavaScript tags:


This is just a very basic example.  The text highlighted in blue is the matched text that would theoretically be removed by the input sanitization code.  Here’s a slightly more complex regular expression that covers more ground:


If you happen to come across this type of input validation, your job is to figure out what type of regular expression is being used in the background.  Two good places to start are checking if the expression is case sensitive and checking if the function is recursive.


As you can see, the regular expression is not case sensitive, therefore using capital script tags will avoid being stripped.  Also, if the validation code is not recursive, the code will strip the first set of script tags that we’ve inserted into the middle of another set of script tags.  This will result in valid tags still being formed and executing the JavaScript.  There are many variations of this kind of input validation but it is not recommended.  Let’s move onto another more acceptable form.

Example 3: Character Encoding

Proper character encoding is the first step to effectively protecting applications from injection attacks.  By encoding certain special characters that could potentially be used to inject malicious content, we can nullify any attacks. The following characters should be entity encoded:

Symbol Encoded
< &lt
> &gt
& &amp
/ &#x2F


If you’re assessing an application that is using HTML entity encoding, be sure to check that all characters are properly encoded.  Some application may only encode the less than and greater than symbols.  This still also injections into HTML attributes.  Also be sure to check that the validation solution is consistent across the entire application.  I’ve come across several applications that had spotty input validation which allow certain scripts to be injected in some parts of the application but not others.  This should be an issued raised to the development team and fixed as soon as possible.

There’s much, much more to say about proper encoding, so I’ll direct you to OWASP’s Cross Site Scripting Prevention page.  As usual, OWASP does an exemplary job of detailing exactly what needs to be done to properly protect your applications.

Proof of Concept

Now that you’ve found some injection points, we can make some fun proof of concepts to present.  Alert boxes definitely prove the vulnerability exists, but showing how it can be exploited shows how dangerous they can be.  I’ll go through a few of my favorite examples.

Fake Data Input

Remember that you can always inject a little extra HTML code to support your script injection.  The following example injects a fake form telling the victim that if they enter their credit card number, they’ll be entered for a prize.  Of course, there is no prize, and their card number is sent to an attacker controlled domain (in this case, Google) using an HTTP GET request.  The code is shown below:


When inserted into our injection point, the result appears as follows:


Not totally convincing, but with the right phishing email and a little more work it could be devastating.  The same concept can be applied by injecting a fake login screen or a fake check out screen.

Malware Download

In this example we will use a script to facilitate the download of malware to the victim.  The script is simple, just using the document.open function to open a new window with our download URL.  Don’t worry; it’s not actually malware, just pictures of cute puppies.  The code looks like this:


Pretty simple, right?  That bit of code results in the following:


The download happens automatically and appears as if it is coming from the banking site since it popped up when we navigated there.

Simple Keylogger

This is my favorite example.  I injected this into an application belonging to a development team who didn’t seem to mind the massive risk of cross site scripting. It got their attention (and their boss’s attention) pretty quickly.  The injection uses JavaScript to track all keys pressed, then when the user clicks, it will give a pop up with all of the user’s inputs.  The code looks like this:


And the result looks like this:


That’s all I’m going to cover in what is most likely my longest blog post to date.  Hope you enjoyed and feel free to ask questions, make suggestions, or even share your own proof of concepts.  Thanks for reading!

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

About Jean Fleury

Naval officer, privateer, cyber security professional. Traded in my five-ship squadron for a computer and Burp Suite license.


Web Application Penetration Testing


, , , , , , ,