What Cross Site Scripting Attack Is In MVC

This article explains Cross-Site Scripting attacks and how to prevent them.

Cross-Site Scripting (XSS) attacks are a type of injection, in which malicious scripts are injected into otherwise benign and trusted websites. XSS attacks occur when an attacker uses a web application to send malicious code, generally in the form of a browser side script, to a different end user. The consequences of XSS may range from petty nuisance like displaying an alert box to a significant security risk like stealing session cookies.

Let's create an empty MVC4 application.

Go to File → Project → ASP.NET MVC 4 Web Application and name it mvcDemo.

Click Ok → select empty project.

Then let's create a model in the Models folder and name it Employee.cs.

  1. using System.ComponentModel.DataAnnotations;  
  2. using System.ComponentModel.DataAnnotations.Schema;  
  3. using System.Data.Entity;  
  4.    
  5. namespace mvcDemo.Models  
  6. {  
  7.      [Table("Employee_Master")]  
  8.      public class Employee  
  9.      {  
  10.          [Key]  
  11.          public int Id { getset; }  
  12.    
  13.          [Required]  
  14.          [StringLength(30,ErrorMessage="The {0} must be atleast {2} characters long.",MinimumLength=6)]  
  15.          public string Name { getset; }  
  16.    
  17.          [Required(ErrorMessage="The {0} can not be blank.")]  
  18.          [DataType(DataType.EmailAddress)]  
  19.          [StringLength(50, ErrorMessage = "The {0} must be atleast {2} characters long.", MinimumLength = 12)]  
  20.          public string Email { getset; }  
  21.    
  22.          [Required(ErrorMessage = "The {0} can not be blank.")]  
  23.          [StringLength(1000, ErrorMessage = "The {0} must be atleast {2} characters long.", MinimumLength = 20)]  
  24.          public string Description { getset; }  
  25.      }  
  26.    
  27.      public class EmployeeContext : DbContext  
  28.      {  
  29.          public DbSet<Employee> listEmployee { getset; }  
  30.      }  
  31.  }  
Right-click on the controller folder and add a controller and name it EmployeeController. 

Add Controller

In the auto-generated code I have made some changes in Create.cshtml and run the application.

  1. <div class="editor-label">  
  2.      @Html.LabelFor(model => model.Description)  
  3.  </div>  
  4.    
  5.  <div class="editor-field">  
  6.      @*This code generate text area with 5 row and 25 cols*@  
  7.      @Html.TextAreaFor(model => model.Description, new { rows =5, cols=25 })  
  8.      @Html.ValidationMessageFor(model => model.Description)  
  9.  </div>  
  10.    
And filled in some data.

Your Logo Here

Click on the create button.

Server Error in Application

To prevent this error let's make some changes on EmployeeController. Just add:
  1. [ValidateInput(false)] above Create Method.  
  2.    
  3. [HttpPost]  
  4. [ValidateAntiForgeryToken]  
  5. [ValidateInput(false)]  
  6. public ActionResult Create(Employee employee)  
  7. {  
  8.     if (ModelState.IsValid)  
  9.     {  
  10.         db.listEmployee.Add(employee);  
  11.         db.SaveChanges();  
  12.         return RedirectToAction("Index");  
  13.     }  
  14.     return View(employee);  
  15. }
Note: You cannot add a ValidateInput attribute to any property. If you want to add a property, you will get an error “Attribute 'ValidateInput' is not valid on this declaration type. It is only valid on 'class, method' declarations” and let's rerun the application.

Rerun the Application

Output

Output your logo Here

But I don't want to show HTML tags. So I am making some change to the Index view. I will replace @Html.DisplayFor(modelItem => item.Description) with @Html.Raw(item.Description).

But there is an issue, let's see what happens if someone enters some script code instead of HTML tags. I will add a new record with the following details.

New record with following details

After clicking on the Save button the Index page is showing the following:
Page at LocalHost

So how to prevent this scripting attack?

To add a new Employee:

  1. [HttpPost]  
  2. [ValidateAntiForgeryToken]    
  3. [ValidateInput(false)]    
  4. public ActionResult Create(Employee employee)  
  5. {    
  6.     StringBuilder sb = new StringBuilder();    
  7.     sb.Append(HttpUtility.HtmlEncode(employee.Description));    
  8.      
  9.     sb.Replace("<b>","<b>");    
  10.     sb.Replace("</b>""</b>");    
  11.     employee.Description = sb.ToString();    
  12.      
  13.     string strDes = HttpUtility.HtmlEncode(employee.Description);    
  14.     employee.Description = strDes;    
  15.      
  16.     if (ModelState.IsValid)    
  17.     {    
  18.         db.listEmployee.Add(employee);    
  19.         db.SaveChanges();    
  20.         return RedirectToAction("Index");    
  21.     }    
  22.     return View(employee);    
  23. }   

To edit an Employee:
  1. [ValidateAntiForgeryToken]  
  2. [ValidateInput(false)]  
  3. public ActionResult Edit(Employee employee)  
  4. {  
  5.     StringBuilder sb = new StringBuilder();  
  6.     sb.Append(HttpUtility.HtmlEncode(employee.Description));  
  7.   
  8.     sb.Replace("<b>""<b>");  
  9.     sb.Replace("</b>""</b>");  
  10.     employee.Description = sb.ToString();  
  11.    
  12.     string strDes = HttpUtility.HtmlEncode(employee.Description);  
  13.     employee.Description = strDes;  
  14.     if (ModelState.IsValid)  
  15.     {  
  16.         db.Entry(employee).State = EntityState.Modified;  
  17.         db.SaveChanges();  
  18.         return RedirectToAction("Index");  
  19.     }  
  20.     return View(employee);  
  21. }  
  22.    

Just click on the edit option on the second record and click save. 

Output

Output of your logo here

I hope you enjoy this article.

Happy coding.


Similar Articles