How to handle and display user input to protect ASP.NET web application from XSS in C#

Cross site scripting (or XSS) is the most insidious kind of attack because it’s quite often invisible at first glance.  XSS is based on some code (markup or JavaScript) that is injected into your page. The most common is related to that’s saved in a database after end user input and then loaded in a page.  The next picture shows the case when the end user input is appended to the not properly escaped HTML’s markup and the final results are unexpected:
In case of XSS the code is inserted in the markup and isn’t executed in a database query as in case of SQL injection in C#

In case of XSS the code is inserted in the markup and isn’t executed in a database query as in case of SQL injection in C#

By using JavaScrip, the attacker can easy perform nasty actions like identify theft and session spoofing. With identity theft the attacker could gain access to a website by simply cloning its identity cookie. For this reason, you have to avoid XSS in your applications, but you want to let a user send different kind of content: plain text and markup. In other words you need a method to sanitize the user input before saving it in a database.
ASP.NET is protected by default to malicious user input. If you try to insert some markup or JavaScript code via a GET or POST field, the runtime intercepts the input and produces an error similar to the one shown:
ASP.NET has a default validation mechanism that can intercept potentially dangerous values and display a specific error page in C#

ASP.NET has a default validation mechanism that can intercept potentially dangerous values and display a specific error page in C#

This default behavior will help you, if you need basic protection agains common kinds of attacks.  If you have to store your code to display it later in a page, it’s better to encode it properly in the first place. You can implement this solution by using HtmlEncode method from HttpServerUtility or HttpUtility class in the System.Web namespace. You can also access it directly via the Server property on both HttpContext and Page. You should write the next code in your markup:
string text = HttpUtility.HtmlEncode(SomeText.Text);
This protection is applied in .NET version 4.0 not just to .aspx pages but to all requests, because it’s fired in the BeginRequest event of HttpApplication. If you want to revert to the old behavior, you can change it via web.config:
<httpRuntime requestValidationMode=”2.0″ />
In .NET version 4.0, you can modify the default validation mechanism by writing a new class that inherits from System.Web.Util.RequestValidator and specifying its name in web.config:
<httpRuntime
requestValidationType=”HowToASP.MyValidator, HowToASP” />
There is another way to allow blocked characters (for example < or > ) is to set the the ValidateRequest property on the @Page directive to false:
<%@ Page ValidateRequest=”false” %>
On the left input encoding is not applied and the markup is processed by the browser. On the right input encoding is applied. In both cases changes in web.config and @Page directive are applied in C#

On the left input encoding is not applied and the markup is processed by the browser. On the right input encoding is applied. In both cases changes in web.config and @Page directive are applied in C#

On the left input encoding is not applied and the markup is processed by the browser. On the right input encoding is applied. In both cases changes in web.config and @Page directive are applied.
If you need to support some markup the best way to proceed is to allow only a subset of HTML tags or use some  metalanguage. You can use the next code to remove the real HTML code and then convert basic tags to the new markup based on [ and ] characters:
public static class SecurityUtility
{
// Remove markup
public static string RemoveHtml(string text)
{
return Regex.Replace(text, “<[^>]*>”, String.Empty);
}
// Covert metamarkup
public static string ConvertHtml(string text)
{
text = text.Replace(“[b]”, “<b>”).Replace(“[/b]”, “</b>”);
text = text.Replace(“[i]”, “<i>”).Replace(“[/i]”, “</i>”);
text = text.Replace(“[u]”, “<u>”).Replace(“[/u]”, “</u>”);
return text;
}
}
The next code lines and picture show the SecurityUtility class in action:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text.RegularExpressions;
public partial class MarkupConvert : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
string text;
text = SecurityUtility.ConvertHtml(txtTest.Text);
lblLegend.Text = SecurityUtility.RemoveHtml(text);
}
}

 

This form allows only a subset of markup and uses the left and right square brackets to totally avoid the use of tags in C#

This form allows only a subset of markup and uses the left and right square brackets to totally avoid the use of tags in C#