Preventing Cross-Site Script Attacks with a Custom TextBox Control
Cross-Site Scripting attacks are still a frequent occurance across the web. Fortunately the ASP.NET framework has a built-in protection against this type of attack. But as good as that is, it is still actually limited to a certain degree. So it is a good practice to add your own protection layers to applications, guarding against as many unexpected attacks as possible.
A brief explanation of a Cross-Site Scripting attack would be a hacker injecting some client-side (JavaScript) into the page to usually transfer sensative data to their server. It could also be as simple as changing the data that is displayed on your page to visitors. The point is this can be extremely dangerous and we need to do as much as possible to mitigate our attack surfaces.
A few years ago I wrote a simple Label control, ExSafeLabel, to help guard against this type of attack. I think it is still listed on the http://www.asp.net/ control gallery, even though I do not have the control available anymore (sorry). It was written in the early days of ASP.NET 1.0. ASP.NET 1.1 introduced some core protection against these types of attacks with the ValidateRequest page directive. You have to manually set this to false in order for HTML and JavaScript tags to be submitted to a page. As good as this is, it still does only basic protection for us.
I have thought about this issue for some time now and thought it might be a good idea to create my own textbox that would help lower the potential of this type of attack, ExSafeTextBox. This entry will be an introduction to this control and I will show how to stop some basic stuff, and I hope to expand this control over the next few weeks to stop as much as possible.
The ExSafeTextBox is a simple Web Control that inherits from TextBox. I have added one boolean property AllowAllTags as a flag to apply protection or just let things pass through. A second property overrides the Text property of the TextBox control and applies our protection.
1 Imports System.Text.RegularExpressions
2 Imports System.Web.UI.WebControls
3 Imports System.Web.UI
4
5 ''' <summary>
6 '''
7 ''' </summary>
8 ''' <remarks></remarks>
9 Public Class ExSafeTextBox
10 Inherits System.Web.UI.WebControls.TextBox
11
12 ''' <summary>
13 '''
14 ''' </summary>
15 ''' <value></value>
16 ''' <returns></returns>
17 ''' <remarks></remarks>
18 <DefaultValue("False"), Localizable(True), Bindable(True, BindingDirection.TwoWay), _
19 PersistenceMode(PersistenceMode.EncodedInnerDefaultProperty)> _
20 Public Property AllowAllTags() As Boolean
21 Get
22 Dim bAllowAllTags As Boolean = Me.ViewState.Item("AllowAllTags")
23 If IsNothing(bAllowAllTags) = False Then
24 Return bAllowAllTags
25 End If
26 Return False
27 End Get
28 Set(ByVal value As Boolean)
29 Me.ViewState.Item("AllowAllTags") = value
30 End Set
31 End Property
32
33 ''' <summary>
34 '''
35 ''' </summary>
36 ''' <value></value>
37 ''' <returns></returns>
38 ''' <remarks></remarks>
39 <DefaultValue(""), Localizable(True), Bindable(True, BindingDirection.TwoWay), _
40 PersistenceMode(PersistenceMode.EncodedInnerDefaultProperty)> _
41 Public Overrides Property Text() As String
42 Get
43 Dim text1 As String = MyBase.Text
44
45 If String.IsNullOrEmpty(text1) Then
46 Return String.Empty
47 End If
48
49 If AllowAllTags Then
50 Return Regex.Replace(text1, "", String.Empty)
51 End If
52
53 Return Regex.Replace(text1, "<[^>]*>", String.Empty)
54
55 End Get
56 Set(ByVal value As String)
57 MyBase.Text = value
58 End Set
59 End Property
60
61
62 End Class
The protection comes from executing a regular expression replace method on the text entered in the Textbox. This expression removes any HTML tag from the text. To actually use this control we can add it to Visual Studio's control Toolbox or hand code things in our web project. I have personally included this control in my ExBaseFuncs Library, so you will see it referenced in the code below. You could also add the control source to your App_code directory, instead of a class library.
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="scratch.aspx.vb" Inherits="scratch"
ValidateRequest="false" %> <%@ Register Assembly="ExtremeWebWorks.ExBaseFuncs" Namespace="ExtremeWebWorks" TagPrefix="cc1" %>
<%@ Register Assembly="ExtremeWebWorks.ExBaseFuncs" Namespace="ExtremeWebWorks" TagPrefix="cc1" %>
<DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server">
<head runat="server">
<title>Untitled Page</title> </head> <body>
<body>
</head> <body>
<body>
<form id="form1" runat="server"><div> <cc1:ExSafeTextBox ID="ExSafeTextBox1" runat="server" Width="457px"></cc1:ExSafeTextBox>
<asp:Button ID="Button1" runat="server" Text="Button" /></div></form> </body> </html>
</html>
To see this in action let's enter a potentially harmful script in the textbox and then echo it back with a response.write(). Notice I turned off the
ValidateRequest directive on the page, I did this to test this simple script.

This is an over simplified example, that if droped on the page would cause an alert message box to be displayed. But you can see that this could be potentially much more damaging. With all the great Ajax stuff out there and the bridging technology, think about what could be sent back to the potential bad guy.
Ouch this hurts. Fortunately, the ExSafeTextbox has protected us and we just get some harmless text echoed back on the page.
My next step is to add protection against encoded attacks. It is not that hard for an attacker to encode their JavaScript as ASCII characters, so it just looks like a long string of numbers on the page. Many Black Hat SEO companies use this technique to game the search engine results by doing hidden redirects. This attack would be real hard to pull off, but technically could be done.

These types of attacks are not limited to Microsoft technolgies, but to any web site on any platform. Despite how bad our platform gets pounded by the general media, it is probably one of the more robust, secure platforms and has many safe guards in place. But do not feel safe, instead be steadfast and alert and you will reap the rewards.