Prevent a cross-site scripting attack
First step: recognize the signs and halt an XSS intrusion
An XSS attack leads to undesirable effects. For example, the attacker gains the ability to capture the session information, peer into private user details such as ID, passwords, credit card information, home address and telephone number, social security/tax IDs, and so on. If the targeted Web site doesn't check for this type of malicious code, misuse of the user is probable.
To reduce the risk of having the script identified as malicious, the attacker might encode it with a different encoding method, such as HEX. With this alteration, the Web site displays the malicious content on the page as if the displayed information is the valid content from the site. If the Web application doesn't validate the input, all the attacker has to do is to coax the user to select the malicious hyperlink, after which the Web application collects confidential data from the user. This enables the attacker to capture the user's session and steal the user's credentials, redirect to a page on another Web site, and then insert code that can poison cookies, expose SSL connections, access restricted or private sites, or even trigger a number of such attacks.
The first weapon in the arsenal for stopping this type of abuse is recognizing the areas that are prone to the XSS-style of intrusion.
Discovering XSS vulnerabilities
The following examples are intended to help you recognize the areas that are vulnerable to XSS attack.
A banking malady
Suppose that an attacker wants to gather info on a user of a fictional, popular banking Web site, www.simplebank.com. To log into the Web site, the attacker first enters a test user ID ("test") and password ("test"). When the resulting error page comes back with a message that says that the user ID and password combination is wrong, the hacker finds himself in an ideal situation for inserting malicious code into the Web page. How?
- He first enters the following into the ID text box:
- He then might introduce scripts like those in Listing 1 into the URL that redirects the submitted user information to malicioussite.com.
This code basically passes the user ID and password information of any user logging into the Web site along to the Web site of the attacker.
- Now that the script to hack the user ID and password is ready, the attacker sends e-mails and posts with attractive offers to banking Web site users employing this link.
- Prompted by the attractive offers, users might click on the link and log on to the banking Web site. The malicious script introduced by the attacker is executed by the browser and the data is passed to the hacker's Web site. The rest is a cakewalk for the hacker to log on to the banking Web site with the victim's credentials.
This situation can occur when:
- A Web server does not take adequate steps to ensure that the properly encoded pages are generated.
- An input is not suitably validated.
Online forums and message boards
The most commonly attacked avenues on the Web are search boxes and online forums. An attacker inserts malicious code between scripting tags that the Web page accepts and interprets, using
APPLET tags, depending on the page used. Inserted malicious code can do all sorts of harm by stealing session information or cookies.
Links attached to messages and e-mail
An attacker can send an e-mail about a banking Web site to a user. Suppose the e-mail contains a link with a malicious script embedded into the URL. The user may be prompted to click on the link and log on to the Web site, whereby the attacker can seize the user's log on information.
The same is true on a dynamically generated page if a link has malicious code in it. Consider the example of a URL (see Listing 2) that might be a part of the page.
If the attacker has the application display a set of HTML, trouble may creep in. Both the
IFRAME tags allow for a new URL to load when HTML is displayed.
Search engines that echo the search keyword that was entered are also vulnerable to such attacks. This is because malicious code can be entered as a part of the keyword search input that is executed when the user submits the search. Dangers can include accessing undesirable or private regions of the Web site.
For example, Listing 3 shows a code snippet that executes code on the target computer. The attacker just inserts HTML in this fashion.
Some Web sites might echo the input along with an error message generated by a business validation. If the input string had some maliciously designed script, the script is executed. Unwelcome effects might include compromise of confidential information and creation of requests that can be mistaken for those from a user.
When a user submits a form during e-mail account setup or during submission of a form with data in it, the Web application might show the same information after accepting the information as entered. The input content entered can contain such malicious information that may be executed by the browser. This can lead to leaking of critical information from the session and might expose private avenues of the Web server.
IFRAME tags in HTML allow for a new URL to load during the display of HTML. Certain worms use the load-on-view feature provided by the
IFRAME tag to contaminate systems running browsers.
These are all vulnerabilities when it comes to an XSS-style attack. Next, I'll briefly talk about the prime result of an XSS intrusion.
Stolen cookies: XSS attack results
For example, the code in Listing 4, when clicked on, sends the cookie to www.destination.com/cgi-bin/cookie.cgi and displays it. If you see a page displaying a cookie, then session hijacking of the user's account is possible. This script can be coded in HEX, as well, to reduce the chance of detection. So, the script sends the user's cookies to the attacker's site where the attacker gain all the information needed to wreak havoc.
A user's protection
A user can help reduce his susceptibility to an XSS-style attack in five significant ways:
- Disable scripting when it is not required.
- Do not trust links to other sites on e-mail or message boards. They may contain malicious code with damaging potential.
- Do not follow links from sites that lead to security-sensitive pages involving personal or business information unless you specifically trust them.
- Access any site involving sensitive information directly through its address and not through any third-party sites.
- Get a list of attacks and the sites and boards they happened on and be careful if you need to visit one of them.
Best practices for Web developers
What about the designers and maintainers of Web sites? you can reduce the problem with a variety of ways highlighted in this section, including a checklist at the end for Web developers.
First, validate the input. The following script accepts a parameter and reflects the same on the display.
Listing 5. A vulnerable script that accepts and reflects a parameter
#!/usr/bin/perl use CGI; my $var1 = CGI->new(); my $parameter = $cgi->param('text'); print $var1->header(); print "parameter";
This piece of code is vulnerable to XSS attacks because no check is made to validate the input. The solution is to validate the input and HTML and escape the data before displaying the same. HTML escaping data means that non-alphanumeric characters are internally represented differently; for instance, with the lesser than (<) and greater than (>) signs represented as a string of characters (< and >).
Add input validation in this manner:
$parameter = ~ s/[^A-Za-z0-9 ]*/ /g;
This validation allows only alphanumeric and space characters and filters the rest. You can further strengthen validations by adding:
This snippet actually encodes HTML characters as HTML entity references. Characters like the less than sign
< are encoded as "<" to help filter out such attacks. However, this is the not the end of the solution -- attacks can come in other forms.
You can add input validation to the script by inserting the following line of code before any output. This code eliminates any input other than letters, numbers, and spaces.
HTML::Entities::encode($text); $text =~ s/[^A-Za-z0-9 ]*/ /g;
This script is vulnerable to cross-site scripting attacks because it blindly prints out submitted form data. To get rid of this vulnerability, you can either perform input validation or ensure that user-submitted data is always HTML-escaped before displaying it.
With that in mind,
TaintRequest automates the process of HTML escaping data. It always validates and HTML escapes the content before displaying or printing the data. (Perl has a feature like
Taint mode built into it that can be used for such security checks.) This method ensures that any external data that flows into the program is not used directly for handling files and directories or for executing processes.
Apache::TaintRequest is a very powerful check for preventing such attacks and making the application less vulnerable to XSS hazards.
To activate this feature, insert the following into the httpd.conf file.
Do the following to ensure that the script uses
use Apache::TaintRequest; my $var1 = Apache::TaintRequest->new (Apache->request); my $parameter = $var1->param('parameter'); $r->content_type("text/html"); $r->send_http_header; $parameter =~ s/[^A-Za-z0-9 ]//; $r->print($parameter);
This piece of code takes up tainted data from the user, ensuring protection as it checks that the characters to be printed are only alphanumeric characters and spaces.
The following is a checklist of ways for webmasters and developers to prevent XSS attacks:
- Guarantee that the pages in the Web site return user inputs only after validating them for any malicious code.
- Filter Meta characters in the input while validating it. (This can be a major checkpoint to eliminate XSS attacks. Although it doesn't eliminate all XSS problems, it can alert Web maintainers to inadequacies in a site's security.)
- Do not completely trust Web sites that use HTTPS (Secure Sockets Layer) when it comes to XSS; HTTPS ensures secure connections, but processing of the data entered by the user is internal to the application. If the application has XSS holes, the attacker may send a malicious script that can still be executed by the application and lead to XSS intrusions.
- Convert all non-alphanumeric characters to HTML character entities before displaying the user input in search engines and forums.
- Use testing tools extensively during the design phase to eliminate such XSS holes in the application before it goes into use. (A best practices guide that stresses this is the philosophy of Extreme Programming.)
- Develop some standard or signing scripts with private and public keys that actually check to ascertain that the script introduced is really authenticated. (To implement things on such a large scale, the Internet rules have to be standardized to derive a common methodology with input from major players such as W3C.)
A pound of prevention...
Cross-site scripting attacks pose an immense risk. Attacks can result in problems ranging from identity theft for one user to incursions that involve major financial and security issues for millions of consumers and businesses. Such remedies as input validation and HTML escaping are a start, but they must be applied at all application points that accept data. An application with a single overlooked form field is just as insecure as one that does no checking whatsoever.
This article doesn't cover the complete solution to XSS-style attacks -- I've only discussed the individual approach that users and Web developers can take. Another component to the prevention of these intrusions must come at a global, industry level -- more research and coordination of international standards.
- Read "Understanding Malicious Content Mitigation for Web Developers." This tech tip for Web developers describes in detail the steps you can take to prevent attackers from from using untrusted content to exploit a Web site.
- In "Peer-to-Peer Sharing of Web Applications," learn about the PlugingAPI interface which offers the ability to encode an arbitrary string for appropriate display within an HTML page, an important application-level tool for avoiding cross-site scripting attacks.
- In "Cross-site scripting" by Paul Lee, find some tactics to fix this potentially dangerous security exposure (developerWorks, September 2002).
- Learn to validate input -- one of the first lines of defense in any secure program -- in "Secure programmer: Validating input" by David Wheeler (developerWorks, October 2003).
- In "Secure programmer: Keep an eye on inputs" by David Wheeler, discover how to use the gateways in and out of your program as the first lines of defense against attacks (developerWorks, December 2003).
- Explore Extreme Programming for a host of best practices for developing Web applications that protect against intrusions like XSS.
- Try the CERT Advisory CA-2000-02, a tool for fighting malicious HTML tags or scripts that can occur in a dynamically generated page based on unvalidated input from untrustworthy sources.
- Read further about vulnerabilities to cross-site scripting:
- The CERT Vulnerability Note VU#672683 explains how the Apache Tomcat server's can pass user input directly to a default error page.
- The CERT Vulnerability Note VU#642239 explains how Lotus Domino Server R5 can pass user input directly to a default error page.
- The CERT Vulnerability Note VU#560659 explains how IBM WebSphere's can pass user input directly to a default error page.
- Review What's New in IBM WebSphere Commerce, 5.4 as it the cross-site protection node available in WebSphere (PDF file).
- Check out the WS-Federation specification which defines an integrated model for federating identity, authentication, and authorization across different trust realms and protocols and details how the WS-Federation model is applied to passive requestors such as Web browsers that support the HTTP protocol. It covers cross-site scripting attacks.