Starting from:
$30

$24

Cross Site Scripting Vulnerability Solution

Introduction
Cross site scripting vulnerabilities allow an attacker to execute browser scripts on a victim's machine. The attack is delivered through a benign or trusted web site that contains this vulnerability. In a successful attack, the victim's browser will load the attacking script and execute it.

Most cross site scripting attacks fall into two categories: stored or reflected. Stored cross site scripting attacks have some persistence over time and separate visits. For example, if a script is injected into a public-facing comment, then any user who visits the page containing that comment will be affected. In the case of reflected cross site scripting, the attack originates in a malicious link or web site and is "reflected" off the vulnerable site. For example, if a web site shows an error message whose content is taken from an HTTP request parameter, then an attacker can craft a link where the parameter contains a malicious script; this malicious script is then present on the loaded web page.

Exercise Description
In this exercise, we provide a small HTTP server that prompts visitors for a username and counts the number of times that user clicks a specific link. Once registered, the web site will display the current user's username, the number of times that user has clicked the link, and the link to be clicked. This naive server does not have any form of authentication and does not persistently store the click count. For the purposes of this exercise, we will not consider the implications of these traits. Instead, we will focus on the potential for reflected cross-site scripting. Your objective is to create a link that will direct a victim to the vulnerable site and execute a "malicious" script.

The program has four source files: TargetServer.java, DoActionServlet.java, LoginServlet.java, and ViewPageServlet.java. The servlets are each attached to a URL path on the server, so all requests directed to that path will be handled by that servlet's implementation. The following table summarizes each file's purpose.

Filename
URL Path
Description
TargetServer.java
n/a
Initializes and starts the vulnerable web server. You will not need to change this file.
DoActionServlet.java
localhost:8080/action
Each request to this servlet increments a counter stored with the session that is attached to the request; if no session exists, nothing happens. Requests to this servlet are logged to stdout in the server command line interface. You will not need to change this file until the Cross Site Request Forgery exercise.
LoginServlet.java
localhost:8080/login
Requests to this servlet will create a new session based on a username parameter. If a session already exists, it resets the counter for that session. You may change this file in part of the mitigation for this exercise.
ViewPageServlet.java
localhost:8080/
This servlet displays one of two html pages based on the presence of a session. If there is a session, it shows a link and a counter for how many times the current session has clicked the link. If there is no session, it shows a form for creating a session. You will need to change this file in part of the mitigation for this exercise.
Vulnerability Mitigation
Mitigating a cross site scripting vulnerability can be a complicated and challenging task. A trivial solution is to simply never display user-supplied content on a website, but that is unacceptable for any kind of interactive web experience. The challenge then becomes a matter of restricting, encoding, escaping, and validating any input that must be interpreted by a web browser. For a nearly comprehensive approach to cross site scripting mitigation, see the OWASP Cross Site Scripting Prevention Cheat Sheet.

For the cross site scripting vulnerability present in this exercise, there are many ways to prevent the attack. We will focus on a whitelisting approach. Your objective is to create a whitelist filter that effectively disrupts the attack vector while preserving the functionality of the web site.

Exercise Instructions
This exercise will be completed entirely on the command line terminal of the provided virtual machine. To open the terminal, right-click on the "EXERCISES" directory and select "Open in Terminal". Enter the following command to change into the exercise directory:

$ cd 3.9.1_cross_site_mechanisms
Compile the Program
We provide a Makefile that will compile the program. Every time you change a .java file, you must recompile the program before running it again. Enter the following command to compile the program:

$ make
Run the Program
This program depends on files in the lib directory, so the command to run the server is java
-cp "./lib/*:." TargetServer. You can see that this command is the only line in run.sh, so you can also start the server by entering the following command:

$ ./run.sh
To stop the server, type quit in the command line interface and press enter. To view the web site, open Firefox by clicking the globe icon in the bottom left hand corner of the screen. The server is attached to http://localhost:8080.

The first page you see is the result of ViewPageServlet.java producing a response to the request without a session. You can enter a username and click "Submit" to create a session. This will take you to the second version of our page. Take note of the elements on this page. When you click the "CLICK" link, it will increment your session's counter and refresh the page. The figure below shows an overview of the logical data flow during normal use of the web site.



Try logging into the server and clicking the link. Note that the server command line will log the click and the counter updates. Experiment with the interface until you understand the basic behavior of the program and how the various pieces interact. To stop the server and terminate the program, type quit in the command line interface and press enter.

Note: A very simple but valuable tool is Firefox's Web Developer tools. In particular, the Network tab will provide some more insight as to how the application works. You can access this by pressing Ctrl+Shift+E when in the Firefox browser. Every time you load a page, you will see the HTTP requests that were sent to get there. Try this when you submit the login form to see that the submit button actually sends you to a separate URL with the username as a parameter.

Inspect the Program Code
Now that you understand the basic behavior of the program, it's time to look at the implementation. As mentioned above, this program is implemented in four files. Focus on the ViewPageServlet.java and LoginServlet.java files first. Use your favorite text editor to open these files. Enter the following command to open each file in Nano:

$ nano ViewPageServlet.java $ nano LoginServlet.java
Spend some time looking at the code alongside the above diagram and follow the flow of data through the servlets. Where does a user's input enter the system? How is this input stored and eventually displayed on a page? Can this user input come from a malicious link?

Exploit the Vulnerability
Start thinking of how user input flows through the application to eventually reach a rendered web page. This is the key component of a cross site scripting attack. Your goal is to craft a link that will, when clicked by a victim, execute a script in the victim's browser. In a real attack, this script could be anything from a simple exfiltration script to a powerful malware installation script. For now, we'll keep it to a simple popup window. The string <scriptwindow.alert('hacked!');</script will create a popup that says "hacked" when a browser renders it in normal HTML. This serves as a non-destructive and easy way to check if your cross site scripting exploit was successful. The question now is: "How can we get that string into our victim's web page?" Try to think of some potential attack vectors and test them out with that string.

By now you should see that the username welcome message is the key component of our attack vector. It's easy to see that the username goes directly into the web page, but this is only part of the exploit. We want to force the victim into executing the script, and sending an email with instructions to copy and paste a script into the username field may not be subtle enough. Looking at the diagram and code samples noted above, try to think of a way we can specify a username without submitting the form. Test some of your ideas and see what happens.

If you're stuck, you should look back to our observations in the Web Developer Network tab. The username form submission is just another HTTP request with the username as a parameter. With the Network tab open, submit the form with our attack screen. You should see the "hacked" popup. The first GET request goes to the login servlet. Click on this request to see what our malicious link should be.

Now that we have our malicious URL, the final step is to test it! In a real attack, this URL could be delivered as a link in an email or on an adversary's web site. To test it for this exercise, put the link into the bad_link.html file. Open that html file in Firefox and click on the link. Note that you may get some mis-matched quotation marks due to the attribute on our link. Try switching our script's message to single quotes if you face any problems.

You should eventually get your link to direct a victim to the vulnerable web site and display our popup. Congratulations! You've exploited a cross site scripting vulnerability!

Mitigate the Vulnerability
As mentioned in the introduction, mitigating cross site scripting vulnerabilities takes careful consideration. For this exercise, we will focus on a simple but restrictive mitigation technique: whitelisting. A whitelist is a filter that only allows approved content. This is simple because you can easily come up with a set of "safe" inputs, but it is restrictive because you will inherently disallow many safe inputs that are not included in your list.

Your first mitigation task is to decide what characters can be considered "safe" for rendering in the web browser. An easy answer is to allow only alphanumeric characters, hyphens, and underscores. None of those characters can be construed into a script tag, and they allow at least some reasonable freedom for a username field. However, this would not be sufficient for an international web site. For example, users who speak languages with characters outside of the English alphabet will be limited, especially those with very few overlapping characters like Mandarin or Arabic. The whitelist must now be a set of all characters in all languages that we wish to support.

Next, you must implement this filter programmatically. Regular Expressions are the tool for this job. Regular Expressions define a "pattern" that we can use for searching in strings. In particular, we can create a pattern that defines our whitelist characters and then detect if our untrusted strings contain only those characters. The Java regular expression API includes everything we need and support for many languages. Explore the java.util.regex package for information on how we might do this. Once you have a basic understanding of pattern matching and character classes, you can formulate your whitelist.

Now your task is to implement your filter using the Java regular expression API. The important API call will be Pattern.matches(regex,
input). Devise a way to check the untrusted data against our regular expression and deny any username that does not match our whitelist.

Shut down the server if it is running by typing quit in the command line interface and pressing enter. Implement your whitelist filter and test the exploits you created earlier. Ever time you change a source file, you must run the make command before running the server again. Run the server by executing the run.sh script after compiling with your new changes. Test the implementation You should find that any input not matching our whitelist will cause an error. Make sure to test good inputs to be sure the site still functions normally. Repeat this process until you are satisfied that the cross site scripting vulnerability is mitigated.

Congratulations! You've mitigated the cross site scripting vulnerability in this exercise. Now you should go on to see how we deal with cross site request forgery vulnerabilities.

More products