HTTP request can be easily "spoofed" by simply adding appropriate values to it. It will lead to modifying not-allowed properties, associations and even whole model.
Solutions 1 (Manual):
Don't use automatic DataBinding from HTTP requests and populate all the values manually.
- Full control over the values.
- Lots of additional code.
Solution 2 (Allow):
Explicitly define which properties are allowed to be data bound. It can be done in both MonoRail and ASP.NET MVC by specifying a string with list of object properties. Like so: Allow="FirstName,LastName". See more in MonoRail.
- Easy to define.
- No additional code.
- Hard to keep track of a real property and its name as a string.
- Impossible to allow binding of different properties for different users (eg: Admin can also assign value to Enabled property of a user).
Solution 3 (DTO):
Wrap real business objects with poor Data Transfer Objects and expose them to external world (outside of controllers).
- Safe to pass to external world.
- Save to pass to view (in case views are developed by somebody else)
- No additinal code because of automatic binding.
- Easier to test.
- Reusable for automatic binding for different user roles (using at least inheritance of DTOs).
- Reusable for JSON, XML serialization.
- A bit more code.
Automatic data-binding in ASP.NET MVC and MonoRail is insecure by default. Dot.
Always use one of these 3 solutions. There, of course, are more, but this is what you can get out of the box.
I think the decision should be made this way:
- Solution 1 (Manual) - you are too concerned or really need full control over everything.
- Solution 2 (Allow) - only one user's role can execute the page and you don't need JSON, XML serialization.
- Solution 3 (DTO) - all other cases.