ValidateInput Attribute to Prevent CSS Attack in MVC

This article explains how to prevent Cross Site Scripting (CSS) attacks using the validateInput attribute.

We know that a Cross Site Scripting (CSS) attack is very common and is a well known attack for web applications. If you are unfamiliar with CSS attacks then the following paragraph is for you.

A CSS attack is basically the result of poor form validation, or the input script might inject from a query string but the chances of that are less compared to form validation. How do CSS attacks work? At first the hacker injects some HTML code into a HTML input field and the data along with the HTML tag is saved to the database if we did not check the HTML input string. Now, when there is a need to display the data in a user interface then we will get it from the database and a legitimate browser will parse it as HTML code. If the hacker then injects a normal HTML string then there is no problem at all, haha.. But it does not happen generally. They might inject harmful JavaScript code from an input field that might steel valuable information from the user's computer.

Ok, so this is all about the CSS attack. And I am very sure that you never want to allow a user to inject a HTML element through a form.

In traditional Web Form applications, we use a form validation script (in JavaScript very often) to validate user's input. But the MVC library has done the job for us, we need not to validate or write lengthy code externally.

Here we will see how to prevent a CSS attack using the ValidateInput attribute.

Let's create one simple model as in the following.

public class person

{

   public string personDescription { get; set; }

}

Just for simplicity we have added only one attribute in the model class. Now we will implement the controller to render the view.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using MVC_5.Models;

namespace MVC_5.Controllers

{

    public class personController : Controller

    {

        public ActionResult Index()

        {

            return View();

        }

        public void GetPerson(person p)

        {

        }

    }

}

This is the simple person controller and it will throw the view when the Index() action is called. And in the form submission it will call the GetPerson() action. Fine, let's implement the view to get the form data.

@model MVC_5.Models.person

@{

    Layout = null;

}

<!DOCTYPE html>

<html>

<head>

    <meta name="viewport" content="width=device-width" />

    <title>Index</title>

</head>

<body>

    <div>

        @{

            using (Html.BeginForm("GetPerson", "person"))

            {

                <input type="text" name="personDescription" /> <br />

                <input type="submit" value="Submit Form" />

            }

         } 

    </div>

</body>

</html>

When we run the application we will find the following output screen.

output
We are putting in a HTML element along with data. And once we click on the submit button we will see the following screen.
 
Error

So, in MVC, by default it prevents the HTML element as form data, anyway we can use the ValidateInput attribute to prevent HTML explicitly in this way.
 

public class personController : Controller

{

    public ActionResult Index()

    {

        return View();

    }

    [ValidateInput(true)]

    public void GetPerson(person p)

    {

    }
}

Or we can use the ValidateInput() attribute over the controller.

[ValidateInput(true)]

public class personController : Controller

{

}

And if we want to allow a HTML element through form input, we can just set the true parameter to false. Then it will allow acceptance of a HTML element as input.

Or

We can use the AllowHtml() attribute of the model property, as in the following to allow a HTML element to a certain property only.

public class person

{

    [AllowHtml]

    public string personDescription { get; set; }

}

Conclusion

It's always a best practice to prevent a HTML element from an input field to prevent or at least to reduce CSS attacks.