Solutions to Cross-Site Scripting (XSS) Attack

Recently i wrote an article on Solutions to SQL Injection Attack that have all the great solutions to tackle SQL Injection Attack. In this article, i would like to discuss with you about Cross-Site Scription attack which is also known as XSS attack.

Cross-Site Scripting Attack

What is cross-site scripting attack? You can easily get a definition written on Wikipedia. It is a type of computer security vulnerability typically found in web applications which allow code injection by malicious web users into the web pages viewed by other users. Often look perfectly fine on the end-users side who may be subject to unauthorized access, theft of sensitive data, and financial loss. Here are a few cross-site scripting attack scenarios you may find interesting.

Simple persistent attack

Mallory posts a message to a social network.

When Bob reads the message, Mallory's XSS steals Bob's cookie.

Mallory can hijack Bob's session and impersonate Bob.

DOM-based attack

Mallory sends the URL of a maliciously constructed web page to Alice, using email or another mechanism.

Mallory crafts a URL to exploit the vulnerability, and sends Alice an email, enticing her to click on a link for the URL.

Alice visits the URL provided by Mallory while logged into Bob's website.

The malicious script embedded in the URL executes in Alice's browser, as if it came directly from Bob's server. The script can be used to send Alice's session cookie to Mallory. Mallory can then use the session cookie to steal sensitive information available to Alice (authentication credentials, billing info, etc) without Alice's knowledge.

Persistent

Bob hosts a web site which allows users to post messages and other content to the site for later viewing by other members.

Mallory notices that Bob's website is vulnerable to a type 2 XSS attack.

Mallory posts a message to Bob's website.

Later, Alice views Mallory's message.

Alice's session cookies or other credentials can be taken and sent to Mallory, without her knowledge.

Mallory logs into Bob's website as Alice, and can see sensitive information (billing info etc.), or post messages on her behalf.

Identity Attack

Bob hosts a site that allows users to post messages which includes a stored list of user names as recommendations.

Alice is a regular visitor to the recommendation-based site; she uses an alias to protect her identity.

Mallory knows one or more of Alice's email addresses but not her identity alias.

Mallory uses social engineering to send a disguised recommendation link or the link to a carefully constructed redirect page which recommends a staged posting to Bob's site.

Alice clicks on the link. Her session cookies or willing-login trigger the recommendation.

The above scenarios are taken from Wikipedia itself which i find it most appropriate to demonstrate the danger of XSS attack.

Solutions

It is well said that the responsibility of preventing XSS attack should not only be held by the developers. End user will really required to know this to better protect themselves from such attacks. It is always better to believe in yourself than others when it comes to security. In this article, we will discuss solutions to better secure ourselves and our web application. Although there are many risk with XSS attack, defending against it is much easier than you might though.

Developers

Filter all foreign data

Anything that will store in our database for future display to other user entered by users are consisted as foreign data. Ensure that all these data are being filter correctly will greatly prevent XSS attack from occurring on your website. Although it may sound easy but it does take discipline to always filter these data whenever there is such input. Especially on larger system where many developers are working on it. Simple filter such as htmlentities() can help eliminate many Cross-site scripting concern.

$filter_input = htmlentities($post['userinput'])
#use $filter_input

Use existing functions

Always use existing functions exist on PHP. Functions like htmlentities(), strip_tags(), and utf8_decode() can be useful. Try not to create your own function for filtering purposes as the functions in build in PHP are usually much faster and more secure to be used. Here are some functions that within PHP that are great for valid or filter user input

htmlentities()

strip_tags ()

utf8_decode ()

htmlspecialchars()

ctype_digit()

ctype_alnum()

Use a whitelist approach

Always assume data to be invalid until it is proved valid. This means that checking the length of the given input, validate the correct type, using regular expression to further validate the creditability till the extreme case you can imagine. This will help prevent any circumstances when the filter failed and caused the script to access your website.

Use a strict naming convention

We all know big systems are usually build by a few developers. Hence, it is important to use a strict naming convention so that whenever a developer look at the code he is able to identify what the other developer is trying to accomplished (you never know what some developer will do during refactoring to make the code more efficient. Yes, they remove these important stuff) and whether the data has been tainted.A lack of clarity yields confusion, and this breeds vulnerabilities. It is a good practice for developer to always be suspicious towards these global variables ($_POST, $_GET, $_REQUEST, etc.). An example of such strict naming convention can be illustrate below,

<?php
$clean = array();
#check whether it is a float, this is just a demo and more validation should be applied before it is clean.
if ($_POST['num'] == strval(floatval($_POST['num'])))
{
$clean['num'] = $_POST['num'];
}
#we use clean array onwards.
?>

Initialize your data

It is a good practice to always initialize your data although it is not necessary to do that in PHP. Since any variable that has not been initialize should always be considered as tainted. It is important to untainted it by initialize them. The user does not have another opportunity to send data as the entire HTTP request has been received, hence no data can be injected into your script (even if register_globals is enabled). Assume register_globals is enabled an attacker can easily make our clean variable into a malicious code if we did not initialize it. Consider the following code,

domain.com?clean=malicious_code

because we did not initialize clean array, clean now contains malicious code that may caused damage to our system.

Cookie Security

Another form of cross-site scripting attack is through cookie security. Many website uses cookie for various reason such as store information, retrieve information, track activities and etc,. However, most web applications rely on session cookies for authentication between individual HTTP requests (the remember me box on login page). We all are aware that client script have access to such cookie and simple XSS script can be made to retrieve such authentication to fake user access. To mitigate this particular threat, we can tie session cookies to the IP address of the user who originally logged in, and only permit that IP to use that cookie. but it will obviously break when an attacker is behind the same NATed IP address or web proxy.

Use BBCode

Many website such as forums, blogs, CMS or other communication system provides the ability to enhance that content by posting formatted text. However, these formatted text is vulnerable against Cross-site scripting attack. Many will uses BBCode on their system to provide user with formatted text and at the same time protect themselves against such attack. Consider the following example of BBCode

You can know more about BBCode in Wikipediawhere more example and explanation is being provided on BBCode. However, using such tag doesn't guarantee XSS security. Consider the following attack example within BBCode,

[url=http://hungred.com]Web development bookmark[/url]
to
<a href="http://hungred.com">Web development bookmark</a>.

The above illustrate a normal anchor tag BBCode. However, if i placed a JavaScript into the BBCode, it is still valid in BBCode,

[url=javascript:alert('Got you!')]Web development bookmark[/url]
to
<a href="javascript:alert('Got you!')">Web development bookmark</a>.

That is why whitelist approach is needed to always prevent such attack from coming. Similarly, in some lower versions of Internet Explorer (IE6 and below), URL format is allowed and will execute Javascript which we will have to take care as well.

XSS CheatSheet

End User

Disabled JavaScript

Many end-users (includes developers) who are well aware of XSS attack and the harm that it may bring upon the user will have their JavaScript disabled on their browsers. Since Cross-Site scripting is using JavaScript to harm users. Disabled such feature is the best way to prevent any attack from Cross-Site scripting. Although this will means that many newer site which only deploy JavaScript may not be accessible, this will also means that many developer will have to ensure that their site is fully protected against such attack. Users can disabled JavaScript and only allows those that are trusted. This approach act as a white list approach where only trusted website has JavaScript enabled to prevent any damage from occurring.

Disabled Cookie

User may want to disabled cookie in order to protect themselves against XSS attack or older browser may not even support cookies. Developers will have to think of alternative ways to provides functionality that required cookies than depending on it.

Summary

Developer must ensure the safety of its visitors and build a safer system for end users. On the other hand, end-user (including developers) will need to know the type of attacks used by attackers to prevent such attacks. The solutions above might not be full bullet proof solution for future Cross site scripting attack. Nonetheless, it can be used for discussion on solutions of future such attack.