Thursday, 22 March 2012

Asp.net mvc model binding security.

One of the thing that makes asp.net.mvc so interesting is default model binding. Model binding in simple words allows you to take the posted form data from the view and bind it to the action method's parameter in the controller without any fuss. But there is a security flaw in model binding which everyone using asp.net mvc should know .The problem is, in asp.net mvc controller you cannot be sure what you got as the posted value from the view because it is absolutely possible that an extra property, or an overwritten property which you don't want get passed to the controller which could spell disaster. And in the controller if the property matches the orginal property then the things could get out of hand.

Here's a simple scenario to understand more what I have defined. A person filling a create user form to become the member of the website requiring some payment in the process passed an Isenabled=true property (which we all have) and unfortunately there is a match in the model at the controller and you haven't defined any whitelist properties (which are included at the controller) or any black listed properties which (which we excluded at the controller) then the user will automatically become active. The cycle which was to be followed was that the moderator after viewing if everything was right and the payment is successfully accepted was going to enable him. So there is a voilation of that cycle.


Tools

You can create the scenario by using firebug.

Solution

By using Include or Exclude in the Bind Attribute class we can lock the properties that are allowed in the model.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CreateUser([Bind(Include="UserName, Password,ConfirmPassword EmailAddress")] UserView User)
If there are large quantity of fields you have the option to use exclude to restrict the properties.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CreateUser([Bind(Exclude="IsEnabled")] UserView User)
Other option
   [Bind(Exclude="GroupID")]
    public class Group
    { 
        [Key]
        public int GroupID { get; set; }

        [Required]
        [Display(Name = "Group Name")]
        [StringLength(50)]
        public string GroupName { get; set; }
        [ScaffoldColumn(false)]
        public DateTime? CreatedDate { get; set; }
        [ScaffoldColumn(false)]
        public DateTime? ModifiedDate { get; set; }
    }

No comments:

Post a Comment