Cross-Site Scripting

Description

This SmartAttack reports each page on which it finds cross-site Scripting vulnerabilities.

Impact

Cross-Site Scripting typically involves executing commands in a user's browser to display unintended content, or with the intent of stealing the user's login credentials or other personal information. This information can then be used by the attacker to access web sites and services for which the compromised credentials are valid (e.g., identity theft). In some cases, the attacker might be able to use this information to hijack or further compromise the user's HTTP sessions.

Worst-Case Scenario

An attacker can use your web site to launch attacks against your users. A cross-site Scripting vulnerability in one server in your domain presents a risk to others in its environment since it can become a launching pad for attacks against other servers.

How It Works

Applications sometimes accept user-supplied input without filtering it, and later return that information to other users. Tests using this SmartAttack inject strings that should be rejected or filtered out, and then watch for their appearance on subsequent pages or in alerts.

This SmartAttack can fault inject fields in HTTP queries (which typically correspond to fields in forms), particular HTTP headers, and cookies. By default, it injects fields in HTTP queries.

This SmartAttack walks the traversal and identifies HTTP requests that are candidates for fault injection. For each candidate request, the SmartAttack sends a series of fault-injected requests, trying a variety of problematic strings. The SmartAttack identifies a failure when it detects evidence of the injected value returned on other pages or in alerts.

Because the Cross-Site Scripting SmartAttack detects faults that do not appear in the immediate response to a fault-injected string, it tags each fault injection string with a pair of numbers identifying the current test run and the injection number. This enables it to report which injection produced a fault that was detected at some later point in the traversal.

This SmartAttack can be configured to recognize error pages that are received in response to fault-injected input, allowing it to ignore legitimate responses that might otherwise appear to be faults. In addition, it can be configured to issue warnings when an error page does not appear in response to fault-injected input.

TechnicalDescription

Cross-Site Scripting (typically referred to as XSS) occurs when an attacker can send a malicious script to a different user by relaying the script from an otherwise trusted or innocuous server. These flaws are extensive on the Web and allow an attacker to place malicious code that can execute attacks against other users in the security context of the web servers of the trusted host.

A frequent tactic used by malicious websites is to provide a link or popup containing an offsite link with an embedded executable script. When the user clicks on the link, a request is sent to another server that, if vulnerable, will echo the script back to the victim's browser, exploiting the trust relationship that exists between the victim and the site that returned the script to the user in executable form.

Online message boards, web logs, guestbooks, and user forums where messages can be permanently stored also facilitate Cross-Site Scripting attacks. In these cases, an attacker can post a message to the board with a link to a seemingly harmless site, which subtly encodes a script that attacks the user once they click the link. Attackers can use a wide-range of encoding techniques to hide or obfuscate the malicious script and, in some cases, can avoid explicit use of the <Script> tag. Typically, XSS attacks involve malicious JavaScript, but it can also involve any type of executable active content. Although the types of attacks vary in sophistication, there is a generally reliable method to detect XSS vulnerabilities.

One way to test for XSS vulnerabilities is to verify whether an application or web server will respond to requests containing simple scripts with an HTTP response that could be executed by a browser. For example, Sambar Server (version 5.3) is a popular freeware web server with known XSS vulnerabilities. Sending the server a request such as the following generates a response from the server that will be executed by a web browser:

/testcgi.exe?<SCRIPT>alert("Cookie"+document.cookie)</SCRIPT>

The script is executed by the browser because the application generates an error message containing the original script, and the browser interprets the response as an executable script originating from the server.

All web servers and web applications are potentially vulnerable to this type of misuse, and preventing such attacks is extremely difficult. Consider implementing the following recommendations if one or more XSS vulnerabilities have been detected in your application

To Use

1.       Create a traversal that represents the target application or a subset of specific pages in the application.

2.       Create a new job or open an existing job.

3.       Add the traversal created above to the job.

4.       Add this SmartAttack to the job.

5.       Set the parameters or accept the defaults in the job. (See Parameters below.)

6.       Run the job.

Parameters

Optional

Inject Form Fields (Boolean)

This parameter controls whether HTTP query fields will be injected. By default, all fields will be injected.
The default value is "true".

Inject Cookies (Boolean)

This parameter controls whether individual cookies in the "Cookie" header (if present) will be injected.
The default value is "false".

Inject A Field At A Time (Boolean)

This parameter specifies that fault injection should happen by injecting one item at a time instead of all at once. The injectable items are elements of GET or POST queries, individual headers, or cookies. Field-at-a-time injection can take considerably longer but might uncover vulnerabilities that would not be found with all-at-once injection. (The reason for this is that some forms employ input validation only on some but not all fields. With all-at-once injection, if any of the fields reject an input, vulnerabilities in unvalidated fields will remain undetected.)
The default value is "true".

Stop On First Fault (Boolean)

This parameter controls whether the SmartAttack will stop after finding the first injection value that reveals a vulnerability in a form, or continue to find all injection values that produce faults.
The default value is "true".

Error Page Regular Expression (regular expression)

This parameter specifies a regular expression pattern which will be used to identify error pages by matching a string in their content. Such error pages will be excluded from fault detection. This mechanism is useful as a way of eliminating false positives.
The default value is empty (no regular expression).

URLs To Skip (list of regular expressions)

This parameter specifies a list of regular expression patterns which will be matched against the URL of each HTTP request that is a candidate for fault injection. If the URL matches one of the patterns in the skip list, the request will not be fault injected.
The default value is an empty list.

Fields To Skip (list of regular expressions)

This parameter specifies a list of regular expression patterns which that will be used to identify form field and cookie names that should be excluded from fault injection.
The default value is an empty list.

Injection String Groups (enumeration)

This parameter controls which subsets of fault injection strings are used in a test. The strings are divided into "Set #1," "Set #2," "Set #3," and "Set #4," where the first group consists of just a few fault injection values (those that are typically the most effective) and the following groups add more strings. The fourth group is very large and should be run only when comprehensive testing is the priority and the amount of time consumed by the job run is not. The groups are mutually exclusive and not supersets of one another, and you can choose to run some and not others. Specifying no groups results in all strings being used.
The default is to use the following fault injection string groups: ["Set #1", "Set #2", "Set #3"].

Advanced

Max Traversal Restarts (integer)

This parameter controls whether and how many times a fault injector will attempt to restart a traversal if fault injection interferes with replaying the traversal. The parameter can be set to "0" to prevent the traversal from being restarted.
The default value is "4".

Detection Value File (string)

This parameter specifies the name of the file that contains the fault detection strings for this SmartAttack. This SmartAttack identifies faults by matching observed responses to the strings in this file.
The default value is "
data_FD_ApplicationException.txt" (the file).

Start SmartAttack After Traversal (Boolean)

This is an advanced parameter that controls whether the SmartAttack processing (concurrent browsing, in this case) begins during the traversal or after the traversal has completed. The default is false, meaning that the processing will start during the traversal. In cases where traversals are unable to complete due to the effects of SmartAttack processes during concurrent browsing, setting this parameter to true will postpone concurrent browsing until after the traversal has completed, which allows all of the injectable requests in the traversal to be collected and injected after the traversal is over. While this allows all of the concurrent browsing to occur, it might not occur in the same context or state that it would have during the traversal.
Default = "false"

Skip First N Injectable Requests (integer)

This is an advanced parameter that specifies the number of the injectable request on which fault injection will begin, allowing previous requests to be exempted from fault injection. In some cases, traversals are unable to complete due to fault injection. In such cases, this parameter can be used to pick up fault injection after the point where the traversal was compromised in a previous job run. Because report items for fault injector SmartAttacks identify the number of each request being injected, you can identify the field where you wish to start and enter that number in this parameter.
The default value is "0".

Headers To Inject (list of strings)

This parameter indicates which HTTP headers (if any) will be injected. The parameter should specify a list of strings with HTTP header names. By default, no HTTP headers will be fault injected. Valid headers are "Accept", "Accept-Charset", "Accept-Encoding", "Accept-Language", "Allow", "Authorization", "Cache-Control", "Connection", "Content-Encoding", "Content-Language", "Content-Length", "Content-Location", "Content-MD5", "Content-Range", "Content-Type", "Cookie", "Date", "Expect", "Expires", "From", "Host", "If-Match" "If-Modified-Since", "If-None-Match", "If-Range", "If-Unmodified-Since", "Last-Modified", "Location", "Max-Forwards", "Pragma", "Proxy-Authorization", "Range", "Referer", "TE", "Trailer", "Transfer-Encoding", "Upgrade", "User-Agent", "Via", and "Warning".
The default value is an empty list.

Injection Value File (string)

This parameter specifies the name of the file that contains the fault injection strings for this SmartAttack. Each SmartAttack that involves fault injection is associated with its own unique file (set of inputs), except for Buffer Overflow and Format String, which do not require separate sets of inputs.
The default value is "
data_FI_CrossSiteScripting.txt" (the file).

Require Error Page (Boolean)

This parameter controls whether Cenzic Hailstorm will issue a warning if an error page does not appear in response to a fault-injected input. This parameter only takes effect if an "ErrorPageMatchExpr" has been specified.
The default value is "false".

Skip Equivalent Requests (Boolean)

This parameter controls whether the SmartAttack will skip fault injection for requests that are equivalent to ones that have already been injected. Requests are considered equivalent if their query element names are the same, even if the query values differ.
The default value is "true".

Distinguish Request Cookie (Boolean)

This parameter only takes effect if the skipEquivalentRequests parameter is true. This parameter controls whether the SmartAttack will consider cookie values when determining whether requests are equivalent.
The default value is "false".

Max Requests With Same URL (integer)

This parameter sets the maximum number of requests that will be injected that have the same base URL, but different queries.
The default value is "15".

Report Messages

This SmartAttack generates the following report output:

Pass: "No cross-site Scripting vulnerabilities detected."

Vulnerabilities:  "Cross-site Scripting vulnerability detected."

Warnings:

 "No error page in response to cross-site Scripting fault injection."

 "Possible cross-site Scripting vulnerability."

Remediation

The following general recommendations can help mitigate the risk associated with Cross-Site Scripting vulnerabilities. This is a complex problem area so there is no one simple fix or solution:

·         Ensure that your web application validates all forms, headers, cookie fields, hidden fields, and parameters, and converts scripts and script tags to a non-executable form.

·         Ensure that any executables on your server do not return scripts in executable form when passed scripts as malformed command parameters.

·         Consider converting JavaScript and HTML tags into alternate HTML encodings (such as "<" to "&lt;>.

·         If your site runs online forums or message boards, disallow the use of HTML tags and Scripting in these areas.

·         Keep up with the latest security vulnerabilities and bugs for all production applications and servers.

·         Update your production servers with the latest XSS vulnerabilities by downloading current patches, and perform frequent security audits on all deployed applications.

The root cause of Cross-Site Scripting is a failure to filter hazardous characters from web application input and output. The two most critical programming practices you can institute to guard against Cross-Site Scripting are:

·         Validate Input

·         Encode output

Always filter data originating from outside your application by disallowing the use of special characters. Only display output to the browser that has been sufficiently encoded. When possible, avoid simple character filters and write routines that validate user input against a set of allowed, safe characters. Use regular expressions to confirm that data conforms to the allowed character set. This enhances application security and makes it harder to bypass input validation routines.

There are different tools you can use to validate and encode your data, depending upon your development environment. Your goal in remediating Cross-Site Scripting attacks is to filter and encode all potentially dangerous characters so that the application does not return data that the browser will interpret as executable.  Any unescaped or unecoded data that is returned to the browser is a potential security risk.

The following characters can be harmful and should be filtered whenever they appear in the application input or output. In output, you should translate these characters to their HTML equivalents before returning data to the browser.

>     <   (     )     [     ]     '     "     ;     :     /     |

PHP

The following PHP functions help mitigate Cross-Site Scripting Vulnerabilities:

Strip_tags() removes HTML and PHP scripting tags from a string.

Utf8_decode() converts UTF-8 encoding to single byte ASCII characters. Decoding Unicode input prior to filtering it can help you detect attacks that the attacker has obfuscated with Unicode encoding.

Htmlspecialcharacters() turns characters such as &,>,<," into their HTML equivalents. Converting special characters to HTML prevents them from being executable within browsers when outputted by an application.

Strtr() filters any characters you specify. Make sure to filter  "; : ( )" characters so that attackers cannot craft strings that generate alerts. Many XSS attacks are possible without the use of HTML characters, so filtering and encoding parentheses mitigates these attacks. For example:

" style="background:url(JavaScript:alert(Malicious Content));

ASP.NET

With ASP.NET, you can use the following functions to help prevent Cross-Site Scripting:

·         Constrain input submitted via server controls by using ASP.NET validater controls, such as RegularExpressionValidator, RangeValidator, and System.Text.RegularExpression.Regex. Using these methods as server-side controls to limit data input to only allowable character sequences by validating input type, length, format, and character range.

·         Use the HtmlUtility.HtmlEncode method to encode data if it originates from either a user or from a database. HtmlEncode replaces special characters with their HTML equivalents, thus preventing the output from being executable in the browser. Use HtmlUtility.UrlEncode when writing URLs that may have originated from user input or stored database information.

·         Use the HttpOnly cookie option for added protection.

·         As a best practice, you should use regular expressions to constrain input to known safe characters. Do not rely solely on ASP.NET validateRequest, but use it in addition to your other input validation and encoding mechanisms.

Java

When it comes to writing some validation code, there are two main choices: filtering and encoding.

Vulnerable code:

Consider the following code:

              <% String sid = request.getParameter("sid"); %>

                ...

                Student ID: <%= sid %>

This code functions correctly when the values of name are as expected. Since there is no validation of this, things can go awry if the inputs are not as expected. For example, a javascript can be made to execute that steals cookies. Remediation to prevent these problems is outlined below.

Secure code:

Filtering:

There are two types of filtering: positive and negative filtering.

Positive Filtering:

The safest and most prevalent method of preventing against attack is to only accept data that is valid and reject everything else. For example, if the data is expected to be alphanumeric, then any input that is not should be rejected.

  String Str = request.getParameter("input");

  String Pattern = "^\\d+$";

  if (!Str.matches(Pattern))

        /* invalid input, take appropriate action*/

Negative Filtering:

Even though this is the ideal mechanism, it might not be practical to reject all data. For example, in blogging applications, it might be a requirement to allow the user to use html format to input data. In this case, check for the existence of special characters within the data. These characters can be replaced with other characters, such as a space.

  /* regular expression that

   * tests for the existence of malicious characters

   * and replaces them with a space. */

  String Pattern="[<>{}\\[\\];\\&]";

  String Str = s.replaceAll(Pattern," ");

Encoding:

To ensure that the generated pages are properly encoded for a Web server, use a simple mechanism rather than an application.  Pass each character in the dynamic content through an encoding function where the scripting tags in the dynamic content are encoded.

A tag library is made up of one or more classes and an XML tag library description file, which dictates the new tag names and valid attributes for those tags. Tag handlers determine how the tags, their attributes, and their bodies are interpreted and processed at request time from inside a JSP page.

Examples of Encoding Functions are below:

public int Encode () throws Exception {     

     StringBuffer sbuf = new StringBuffer();

     char[] chars = property.toCharArray();

     for (int i = 0; i < chars.length; i++)

          sbuf.append("&#" + (int) chars[i]);

     try

     {

         pageContext.getOut().print(sbuf.toString());    

     } catch (IOException ex) {

         throw new JspException(ex.getMessage());    

     }

     return;

 }

Java HTML Encoding Function

 public static String HTMLEncode(String aTagFragment){

     final StringBuffer result = new StringBuffer();

     final StringCharacterIterator iterator = new

                                    StringCharacterIterator(aTagFragment);

     char character =  iterator.current();

     while (character != StringCharacterIterator.DONE )

     {

       if (character == '<')

            result.append("&lt;");

       else if (character == '>')

            result.append("&gt;");

       else if (character == '\"')

            result.append("&quot;");

       else if (character == '\'')

            result.append("&#039;");

       else if (character == '\\')

             result.append("&#092;");

       else if (character == '&')

             result.append("&amp;");

       else {

            //the char is not a special one

            //add it to the result as is

            result.append(character);

       }

       character = iterator.next();

     }

     return result.toString();

  }

References

OWASP Guide to Building Secure Web Applications
http://www.owasp.org/

 OWASP Frequently Asked Questions on Web Application Security  http://www.owasp.org/documentation/appsecfaq

Preventing the Cross-Site Scripting Vulnerability
http://www.giac.org/practical/GSEC/Deyu_Hu_GSEC.pdf

Detection of SQL Injection and Cross-site Scripting Attacks
http://www.securityfocus.com/infocus/1768

The Cross-Site Scripting FAQ
http://www.cgisecurity.com/articles/xss-faq.shtml

CERT Advisory on Malicious HTML Tags
http://www.cert.org/advisories/CA-2000-02.html

CERT "Understanding Malicious Content Mitigation" http://www.cert.org/tech_tips/malicious_code_mitigation.html

Cross-Site Scripting Security Exposure Executive Summary: http://www.microsoft.com/technet/treeview/default.asp?url=/technet/security/topics/ExSumCS.asp

Understanding the cause and effect of CSS Vulnerabilities: http://www.technicalinfo.net/papers/CSS.html

OWASP Guide to Building Secure Web Applications and Web Services, Chapter 8: Data Validation http://www.owasp.org/documentation/guide/

 How to Build an HTTP Request Validation Engine (J2EE validation with Stinger) http://www.owasp.org/columns/jeffwilliams/jeffwilliams2

 Have Your Cake and Eat it Too (.NET validation) http://www.owasp.org/columns/jpoteet/jpoteet2