Cross-Site Scripting

Excerpt from Professional ASP.NET 3.5 Security, Membership, and Role Management with C# and VB

By Bilal Haidar 
 
Cross-site scripting, also known as XSS or CSS, is a direct result of not having proper user input validation and failing to encode output to be displayed. The consequences of having improper input validation have been mentioned explicitly in detail. XSS is no different!

For instance, a user enters a public Forum, adds a post to a current or new thread that includes malicious script. The application, if there is improper user input validation and/or encoding for data embedded in the response, takes the input as is and stores it in the database. Now, any user who accesses the same page would have the malicious script executed silently when the application fails to encode the response. The browser is not able to distinguish between harmful and safe scripts. Whatever response the browser receives from the server is simply executed on the client-side. The malicious script could be an annoying one like displaying a pop-up message. Other malicious scripts might be more harmful and could steal stored authentication cookies and send them silently to the attacker.
An attacker usually looks for web applications that redisplay the text that was typed in the input fields via the query string, especially in the case of a search engine, or even a failed trial to validate credentials on a login page. To protect against XSS, you should consider all input as malicious that requires input validation, encoding for all output, in case it contains HTML characters, regardless of the source for such data.
Validating input has been thoroughly discussed. Accordingly, the input data should be well-validated by checking that the correct type is received, the format of the input data is correct, and that the length and range of values are acceptable. ASP.NET validation controls like  RegularExpressionValidator  and RangeValidator  play an important role in addition to the  Regex  class in the .NET framework that you can use to validate HTML input fields on the server-side. Programmatic checking for the type of input text can also be accomplished using the type-checking methods in the .NET framework like the Int32.TryParse() method.
As discussed previously, always encode whatever input text you receive from the client-side. The .NET framework provides the System.Web.HttpUtility.HtmlEncode()  method to properly encode text before it is processed, whether for storage into the database or storage into files. Encoding text that includes HTML tags converts some of the tags into a different form. For instance, the space character is converted to &nbsp; and the<character gets converted to &lt;. In addition, if you need to embed URLs in the response on the server you can use the System.Web.HttpUtility.UrlEncode() method to properly encode the URL. Encoding not only covers the input fields, but also cookies, session variables, query strings, and database access methods. Any source of input data can be a sourceof harm to your applications.

When talking about encoding output to be displayed on the client-side, it is important to limit the ways in which data entered by end-users can be represented by the application on the server-side. Using a limited character set prevents malicious users from using canonicalization and multi-byte escape sequences to bypass the input validation routines on the server-side code. ASP.NET allows you to specify the character set in three different areas:
 
asp Code:
<meta http-equiv="Content Type" content="text/html; charset=ISO-8859-1" />
 
The first option is to use the HTML meta tag in the <head> section of an .aspx page. The above markup line sets the character set of the page to ISO Latin 1 (ISO-8859-1), which is the default character set for early versions of HTML and HTTP. In fact, the ISO Latin 1 is limited but it is recommended to use in your pages.
 
asp Code:
<% @ Page ResponseEncoding="ISO-8859-1" RequestEncoding="ISO-8859-1"%>
 
The second way to specify the character set is to set the ResponseEncoding and RequestEncoding properties on the .aspx page directive, as follows:
 
asp Code:
<configuration>
   <system.
web>
      <globalization
         requestEncoding=
"iso-8859-1"
         responseEncoding=
"iso-8859-1"/>
   </system.
web>
</configuration>
 
The third way is to make use of the <globalization> section in the web.config configuration file.

Protecting against harmful user input starts by enabling the ValidateRequest public property on the Page class. By default, request validation is enabled in any ASP.NET application. This property insures that no harmful scripts or HTML tags can ever be sent from the client-side to the server-side. However, as mentioned above, in some cases, there is a need to allow users to enter HTML formatting tags, for example, in a Rich Text Editor. As discussed earlier, you can do some character conversions on the client-side and convert back to the original text on the server-side! Enabling/disabling request validation takes two forms. The first is shown here:
 
csharp Code:
<%@ Page Language="C#" ValidateRequest="false" %>
 
vbnet Code:
<%@ Page Language="Vb" ValidateRequest="false" %>
You can configure this property on a page-level as the code snippet shows. The second form is as follows:
 
asp Code:
<system.web>
  <pages validateRequest=
"true" />
</system.
web>

 
This way, you can configure validation at the application-level by configuring the <pages> configuration sections inside the web.config configuration file. Figure 18-6 below shows the page that ASP.NET generates when request validation is enabled and a user enters some HTML tags or any other JavaScript scripts.
 
Figure 18-6 

The ASP.NET and Application Consulting & Engineering (ACE) teams at Microsoft provided the Microsoft Anti-Cross Site Scripting Library V1.5 encoding library that is designed to help developers protect their web applications from cross-site scripting attacks. This library differs from other encoding libraries in that it uses the principle-of-inclusions technique. This technique is similar to the concept of whitelisting and it works by defining a set of allowable or valid set of characters and encoding anything outside this set:
 
csharp Code:
namespace Microsoft.Application.Security
{
   
publicclass AntiXss {
 
   
publicstaticstring HtmlEncode(string s);
   
publicstaticstring HtmlAttributeEncode(string s);
   
publicstaticstring JavaScriptEncode(string s);
   
publicstaticstring UrlEncode(string s);
   
publicstaticstring VisualBasicScriptEncode(string s);
   
publicstaticstring XmlEncode(string s);
   
publicstaticstring XmlAttributeEncode(string s);
 
}
}
 
vbnet Code:
Namespace Microsoft.Application.Security
   
PublicClass AntiXss
       
Public Shared Function HtmlAttributeEncode(ByVal s AsString)AsString
       
Public Shared Function HtmlEncode(ByVal s AsString)AsString
       
Public Shared Function JavaScriptEncode(ByVal s AsString)AsString
       
Public Shared Function UrlEncode(ByVal s AsString)AsString
       
Public Shared Function VisualBasicScriptEncode(ByVal s AsString)AsString
       
Public Shared Function XmlAttributeEncode(ByVal s AsString)AsString
       
Public Shared Function XmlEncode(ByVal s AsString)AsString
   
EndClass
EndNamespace
 
This code shows the set of methods that are available by the library that you can use to protect against the input you receive from end-users, and to properly send encoded data to the client-side.

The
HtmlEncode() method is used to encode text that is to be displayed in the context of HTML. The container that will hold the encoded text can be any ASP.NET server control that can display text:
 
csharp Code:
this.lblName.Text = Microsoft.Security.Application.AntiXss.HtmlEncodethis.txtName.Text);
 
vbnet Code:
Me.lblName.Text = Microsoft.Security.Application.AntiXss.HtmlEncode(Me.txtComments.Text)
 
The HtmlEncode() method can also be used when displaying text directly inside HTML tags using <%= %> block:
 
asp Code:
<% = Microsoft.Security.Application.AntiXss.HtmlEncode(this.txtName.Text)%>
 
The HtmlAttributeEncode() method is used to encode attributes when embedding HTML elements into the page and specifying its attributes that might be used by attackers to send malicious and harmful scripts to the server:
 
csharp Code:
this.ltSeperator.Text =
     
"<hr noshade size="+
     Microsoft.
Security.Application.AntiXss.HtmlAttributeEncode(
                               
this.txtSizeInPixels.Text)+
     
">";
 
vbnet Code:
Me.ltSeperator.Text = _
   
"<hr noshade size=" & _
    Microsoft.
Security.Application.AntiXss.HtmlAttributeEncode( _
   
Me.txtSizeInPixels.Text) & _
">"
 
This example shows how to safely encode HTML attributes when embedding dynamic HTML elements on the page. The other methods available in the library are used in the same manner as the above sample methods. You can read more about the Anti-Cross Site Scripting library by reading the article on MSDN at: http://msdn.microsoft.com/en-us/library/aa973813.aspx.

 

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *