Friday 8 July 2016

Some Notes about ASP.NET Request Validation and Cross Site Scripting

ASP.NET framework has a built-in feature enabled by default to protect application against Cross Site Scripting (XSS) attack. It uses Request Validation feature that checks query string, cookie and posted form values to make sure that those inputs do not contain malicious script. It will throw an error if it encounters malicious script.


Request Validation version
For the recent version of ASP.NET framework, we should use the latest validation mode. In our web.config file, it should have something like:
<httpRuntime requestValidationMode="4.5" targetFramework="4.5" />
ASP.NET version 4.0 should use   requestValidationMode="4.0"


Turning off Request Validation feature in the application
We could also turn off Request Validation feature and only have this feature on some pages. To do this, in web.config set
<pages validateRequest="false" /> 
then set the validation feature on the pages that we would like to have it
<@ Page ValidateRequest="true" %> 


Disable Request Validation in a Controller
We also can disable Request Validation feature for a particular controller by setting [ValidateInput(false)] attribute:
[ValidateInput(false)] 
public ActionResult Index(MyModel m) 
{ 
    . . . 
} 


Disable Request Validation on a class property
To disable the feature at a more granular level, we can use [AllowHtml] attribute on a class property:
public class MyModel 
{ 
    public string MyProperty1 { get;  set; } 

    [AllowHtml] 
    public string MyProperty2 { get; set; } 

    . . . 

} 


Encoding input data
If we would like to allow input data that contains HTML or JavaScript codes, we can encode the input with HtmlEncode() function that are provided by ASP.NET framework. In ASP.NET version 4.5 or above, they have included AntiXss Library in the System.Web.Security.AntiXss namespace. This library prevents XSS better as it uses whitelisting approach compared to the default one which uses blacklisting approach. To set AntiXss Library as the default library for encoding, specify the encoderType in httpRuntime node in web.config:
<httpRuntime  . . .  encoderType="System.Web.Security.AntiXss.AntiXssEncoder" />


Sanitising data
When we need to accept HTML format data, then we should sanitise the data first from any malicious codes. The AntiXss Library 4.3.0 contains sanitiser functionalities however this has reached an end of life. The newer version that is included with ASP.NET 4.5 does not contain sanitiser.

We have some options to add sanitation functionality, a couple of those are:
- Write our own custom method using HTML Agility Pack. See this article for an example
- Use a third party library such as the open source HtmlSanitizer

Using the open source HtmlSanitizer library is easy. We can download the package from NuGet. Below is an example of a simple usage of it:
var sanitiser = new HtmlSanitizer(); 
sanitiser.Sanitize(inputString); 

If we would like to disallow some HTML tags, just use .AllowedTags.Remove() method. For example:
sanitiser.AllowedTags.Remove(“img”); 

Below is an example of a method that uses reflection to sanitise string properties of an object passed to it:
public object CleanStringsFromXSS(object data) 
        {  
            var sanitiser = new HtmlSanitizer(); 

            PropertyInfo[] properties = data.GetType().GetProperties(); 
            foreach (PropertyInfo property in properties) 
            { 
                Type propertyType = property.PropertyType; 
                if ((propertyType == typeof(string)) && (propertyType != null)) 
                { 
                    object value = property.GetValue(data); 
                    if (value != null && property.CanRead && property.CanWrite) 
                    { 
                        string sanitisedValue = sanitiser.Sanitize(value.ToString()); 
                        property.SetValue(data, sanitisedValue); 
                    } 
                } 
            } 

            return data; 
        } 


Request Validation vulnerabilities
There is a known vulnerability in Request Validation. Some types of JSON (JavaScript Object Notation) postback can bypass this feature. Therefore it is important to scan JSON input manually. The sanitation library above can be used to check or sanitise malicious codes.


References:
OWASP: ASP.NET Request Validation
Preventing XSS in ASP.NET Made Easy