How To Recognize Cross Site Scripting Vulnerabilities

From Guidance Share

Jump to: navigation, search

Contents

Overview

Your code is vulnerable to cross-site scripting (XSS, also referred to as CSS) attacks wherever it uses input parameters in the output HTML stream returned to the client. Even before you conduct a code review, you can run a simple test to check if your application is vulnerable to XSS. Search for pages where user input information is sent back to the browser.

XSS bugs are an example of maintaining too much trust in data entered by a user. For example, your application might expect the user to enter a price, but instead the attacker includes a price and some HTML and JavaScript. Therefore, you should always ensure that data that comes from untrusted sources is validated. When reviewing code, always ask the question, "Is this data validated?" Keep a list of all entry points into your ASP.NET application, such as HTTP headers, query strings, form data, and so on, and make sure that all input is checked for validity at some point. Do not test for incorrect input values because that approach assumes that you are aware of all potentially risky input. The most common way to check that data is valid in ASP.NET applications is to use regular expressions.

You can perform a simple test by typing text such as "XYZ" in form fields and testing the output. If the browser displays "XYZ" or if you see "XYZ" when you view the source of the HTML, then your Web application is vulnerable to XSS. If you want to see something more dynamic, inject <script>alert('hello');</script>. This technique might not work in all cases because it depends on how the input is used to generate the output.

The following process helps you to identify common XSS vulnerabilities:

Identify Code That Outputs Input

View the page output source from the browser to see if your code is placed inside an attribute. If it is, inject the following code and retest to view the output.

"onmouseover= alert('hello');"

A common technique used by developers is to filter for < and > characters. If the code that you review filters for these characters, then test using the following code instead:

&{alert('hello');}

If the code does not filter for those characters, then you can test the code by using the following script:

<script>alert(document.cookie);</script>;

You may have to close a tag before using this script, as shown below.

"></a><script>alert(document.cookie);</script>

Searching for ".Write"

Search for the ".Write" string across .aspx source code and code contained in any additional assembly you have developed for your application. This locates occurrences of Response.Write, and any internal routines that may generate output through a response object variable, such as the code shown below.

public void WriteOutput(Response respObj)
{
  respObj.Write(Request.Form["someField"]);
}

You should also search for the "<%=" string within .aspx source code, which can also be used to write output, as shown below:

<%=myVariable %>

The following table shows some common situations where Response.Write is used with input fields.


Identify Potentially Dangerous HTML Tags and Attributes

While not exhaustive, the following commonly used HTML tags could allow a malicious user to inject script code:

  • <applet>
  • <body>
  • <embed>
  • <frame>
  • <script>
  • <frameset>
  • <html>
  • <iframe>
  • <img>
  • <style>
  • <layer>
  • <ilayer>
  • <meta>
  • <object>

HTML attributes such as src, lowsrc, style, and href can be used in conjunction with the tags above to cause XSS.

For example, the src attribute of the <img> tag can be a source of injection as shown in the following examples.

<IMG SRC="javascript:alert('hello');">
<IMG SRC="java
script:alert('hello');">
<IMG SRC="java
script:alert('hello');">

The <style> tag also can be a source of injection by changing the MIME type as shown below.

<style TYPE="text/javascript">
alert('hello');
</style>

Check to see if your code attempts to sanitize input by filtering out certain known risky characters. Do not rely upon this approach because malicious users can generally find an alternative representation to bypass your validation. Instead, your code should validate for known secure, safe input. The following table shows various ways to represent some common characters:

Identify Code That Handles URLs

Code that handles URLs can be vulnerable. Review your code to see if it is vulnerable to the following common attacks:

If your Web server is not up-to-date with the latest security patches, it could be vulnerable to directory traversal and double slash attacks, such as: http://www.YourWebServer.com/..%255%../winnt http://www.YourWebServer.com/..%255%..//somedirectory

If your code filters for "/", an attacker can easily bypass the filter by using an alternate representation for the same character. For example, the overlong UTF-8 representation of "/" is "%c0f%af" and this could be used in the following URL: http://www.YourWebServer.com/..%c0f%af../winnt

If your code processes query string input, check that it constrains the input data and performs bounds checks. Check that the code is not vulnerable if an attacker passes an extremely large amount of data through a query string parameter. http://www.YourWebServer.com/test.aspx?var=InjectHugeAmountOfDataHere


Check That Output Is Encoded

While not a replacement for checking that input is well-formed and correct, you should check that HtmlEncode is used to encode HTML output that includes any type of input. Also check that UrlEncode is used to encode URL strings. Input data can come from query strings, form fields, cookies, HTTP headers, and input read from a database, particularly if the database is shared by other applications. By encoding the data, you prevent the browser from treating the HTML as executable script.


Check for Correct Character Encoding

To help prevent attackers using canonicalization and multi-byte escape sequences to trick your input validation routines, check that the character encoding is set correctly to limit the way in which input can be represented.

Check that the application Web.config file has set the requestEncoding and responseEncoding attributes configured by the <globalization> element as shown below.

<configuration>
  <system.web>
     <globalization
        requestEncoding="ISO-8859-1"
        responseEncoding="ISO-8859-1"/>
  </system.web>
</configuration>

Character encoding can also be set at the page level using a <meta> tag or ResponseEncoding page-level attribute as shown below.

<% @ Page ResponseEncoding="ISO-8859-1" %>

Check the validateRequest Attribute

Web applications that are built using the .NET Framework version 1.1 perform input filtering to eliminate potentially malicious input, such as embedded script. Do not rely on this, but use it for defense in depth. Check the <pages> element in your configuration file to confirm that the validateRequest attribute is set to true. This can also be set as a page-level attribute. Scan your .aspx source files for validateRequest, and check that it is not set to false for any page.

Check the HttpOnly Cookie Option

Internet Explorer 6 SP 1 supports a new HttpOnly cookie attribute that prevents client-side script from accessing the cookie from the document.cookie property. Instead, an empty string is returned. The cookie is still sent to the server whenever the user browses to a Web site in the current domain.

Check the <frame> Security Attribute

Internet Explorer 6 and later supports a new security attribute on the <frame> and <iframe> elements. You can use the security attribute to apply the user's Restricted Sites Internet Explorer security zone settings to an individual frame or iframe. For more information, see the "Cross-Site Scripting" section in Chapter 10, "Building Secure ASP.NET Pages and Controls."

Check the Use of the innerText and innerHTML Properties

If you create a page with untrusted input, verify that you use the innerText property instead of innerHTML. The innerText property renders content safe and ensures that script is not executed.

Personal tools