Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it dangerous for views to directly use domain models?

I've used an EF code-first approach to define my DB structure. Currently, I am passing the EF entity classes directly into some of my views in an MVC application. This makes it easy to populate and save the views because I can just directly have a repository give me my populated EF class, and if my controller receives an EF entity class in a postback, I can (if validation is OK) pass that straight through to the repository to save it. However, is this potentially a security risk? If there are properties on an entity class that I don't want modified, could the client submit those properties back as part of the postback and modify them anyway? For example, say I have a view to edit a user to which I pass this EF model:

public class User {
    [Required]
    public string Firstname { get; set; }
    [Required]
    public string Surname { get; set; }
    public DateTime DOB { get; set; }
    public bool IsDisabled { get; set; }
}

I might expose Firstname, Surname, and DOB as editable form fields, but I don't want the user to be able to set IsDisabled and disable their account. What's the best way to guard against this? Perhaps one should only use domain models in views directly when one thinks it's alright for every property persisted by that domain model to be settable by the user, or when one is just using that domain model to display things, rather than save things back to a data store?

like image 733
Jez Avatar asked Dec 27 '22 16:12

Jez


2 Answers

Yes, it can be dangerous to pass Entities directly to your view. Technically, the problem is when you model bind to entities directly.

Yes, it's very possible for the situation you presented to occur. Even worse. Suppose you pas a User object, then an attacker could submit a post value to do something like set IsAdmin true, or alter the roles assigned to the user.

Of course, all this depends on the user knowing (or being able to guess) the structure of your data. That may not be as difficult as it seems, since we often have tell-tale signs in our generated HTML that give hints.

There are two solutions to this problem:

1) Use view models. The view model only contains the data that's allowed in the view. You can also control what data gets copied back into the entity model.

2) you can use the [Bind] attribute to specify exclusions and inclusions to white-list and black-list various properties.

I prefer using the first approach, since it's much harder to forget to white-list or black-list something (especially if you change something later and forget to update the list everywhere you bind it). I also feel like [Bind] is cheating and encourages sloppy design.

like image 191
Erik Funkenbusch Avatar answered Jan 13 '23 01:01

Erik Funkenbusch


You are not really supposed to use your entity models as view models, and I think your example here really highlights that better than I have seen anywhere else.

If your controller accepted, upon post, a User then yes, you would be exposing that data to be posted there. If you mapped the posted user directly without checking for invalid submission then you would have persisted the problem into the database.

like image 36
Travis J Avatar answered Jan 13 '23 02:01

Travis J