Tutorials > Setting Up a Development Environment > Cross-site Scripting

9. Cross-site Scripting

  • This article assumes you have completed the previous tutorials up to: Basic SQL Injection
  • Cross-site scripting is the most common website vulnerability.
  • To understand cross-site scripting, you first need to be at least somewhat familiar with JavaScript.
  • In brief, JavaScript is the client-side programming language. Client meaning it gets executed in your browser as opposed to on the server. This allows HTML files to become dynamic.
  • Lets say on our grocery list we wanted Create new item to be a link and have the input hidden at first until you click the link.
  • Alright, so first lets add the link and hide the input in index.php:

    <h3><a href='javascript:void(0);'>Create new item</a></h3>
    <form action='newitem.php' method='post' id='new_item_form' style='display:none;'>
    	<label>Item name:</label>
    	<input type='text' name='item_name' />
    	<input type='submit' value='Add Item' />
    </form>
  • First, we used href='javascript:void(0);' as part of the <a> tag. This tells the browser this is not a normal link and clicking it should not take you to a new page.
  • Second, we set style='display:none;' to the <form> element. Styles can be used to format HTML pages, this uses the display style to hide the form.
  • And lastly, we added id='new_item_form' to the <form> element. This will be used to identify the element in our script.
  • So now our main page will look like this:
  • But clicking Create new item doesn't do anything yet. This is where the real JavaScript comes in.
  • First lets create the function to show the form:

    <script type='text/javascript'>
    function showForm() {
    	document.getElementById("new_item_form").style.display = "block";
    }
    </script>
  • And then add an onclick handler to the <a> tag:

    onclick='showForm();'
  • You create JavaScript blocks using <script type='text/javascript'></script>. The showForm() function uses document.getElementById() which returns a reference to an object in the DOM. Changing the style is one of many things you can do with an element.
  • So now our file looks like:
  • And now if you refresh the page and click Create new item, the form appears.
  • And if we want to get a bit fancier, we can change it to toggle instead:

    <script type='text/javascript'>
    function toggleForm() {
    	var newItemForm = document.getElementById("new_item_form");
    	if (newItemForm.style.display == "block") {
    		newItemForm.style.display = "none";
    	} else {
    		newItemForm.style.display = "block";	
    	}
    }
    </script>
  • Now we've got JavaScript down, so what's this cross-site scripting?
  • Pretty much every website uses JavaScript, so by itself there are few security issues. It becomes a problem when an attacker is able to add their own JavaScript to someone else's website.
  • For instance, if your bank's website was comprimised, an attacker might make it so when you click a link it sends him your bank account information or something. And it might do this in the background so you don't even know it happened.
  • Okay, so how could you execute an XSS (cross-site scripting) attack?
  • Try adding this new item to our grocery list:

    Apples<script>alert('hello');</script>
  • And now when you try going to the main page you get an alert message because the HTML looks like this:

    <td>Apples<script>alert('hello');</script></td>
    
  • Your browser doesn't know the difference between the <script> tag in your name and the real ones so it executes all of them.
  • Displaying an alert is pretty harmless, just annoying, but lets say they wanted to redirect you to their own site that looks exactly the same so they can steal your login credentials. Try adding this item to create a redirect:

    Pasta<script>window.location.href='http://www.google.com/';</script>
  • Okay, so how do we prevent this? Well it's not always easy, which is why it's the most common vulerability. For starters we can use the PHP htmlentities() function on our output in index.php:

    <td><?php echo htmlentities($row['item_name']); ?></td>
  • This converts all applicable characters to HTML entities so that the browser doesn't interpret them as markup.
  • Now our HTML looks like this and does not execute the script:

    <td>Apples&lt;script&gt;alert('hello');&lt;/script&gt;</td>
    

Return to TutorialsNext Tutorial: Cross-site Request Forgery