<

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x

Why you shouldn't use Html.beginForm + UpdateModel on ASP.NET MVC

Published on
9,876 Points
3,776 Views
1 Endorsement
Last Modified:
Approved
I've found this issue almost accidentally, however it seems so clear and logical to me that I'm surprised that there's no specific information on the matter (at least at first glance).

Is not unusual to see people using the beginForm helper on ASP.NET MVC applications, this is true to the point that the creation of a Create/Edit View on VS includes it on your code by default.

This helper just builds a <form> tag saving you some repetitive typing, it gets your current http petition and builds an action and a method for the form. To this point maybe there's nothing that triggers your alarms, however there is. The default method uses your current url, wich can be manipulated directly on the browser by the user, to build the action of the form; this way a malicious user can inject extra parameters on your server call.

Ok, what's the problem? My model classes and controller will deal only with those parameters I define, so...

Well, actually is highly possible that you're using one of the most popular utilities of MVC framework on your form controllers: UpdateModel. This method map the fields on your form action directly into your business model whenever it's possible. It's a huge advantage when dealing with complex and big data structures, as it saves a lot of repetitive coding, however, if your business model has a field that's not published through the form but comes on the HttPost, UpdateModel will recognize it and update the data.

Let's try to put it all together on an actual example:

Suppose you have an application where users can edit some of the data in their profile but cannot update some specific data unless they are have a higher role. Say, for example, that they cannot update their email address.

When you build the editing profile form, you build the restricted fields only if the user on session has the higher role.

Unfortunately, if your form is built with Html.beginForm(), a savvy user can alter the url of the form from something like http://yourApp/Profiles/Edit/<ProfileId> to http://yourApp/Profiles/Edit/<ProfileId>?email=myHomeEmail@mail.com

On loading the altered url, if you look at the source code, you'll see that the generated form is:

<form action="/Profiles/Edit/<ProfileId>?email=myHomeEmail@mail.com" method="post" />

Of course, when your form submits the email parameter will be caught by UpdateModel and included into your business model data update.

This example could seem fairly benign, however the exploit possibilities are far larger.

As an immediate fix I recommend to build <form> tags manually. They are critical enough that they should not be coded automatically. However maybe there are intermediate solutions to this. I have to do some research with beforeUpdate overloads and see if there are any that allows you a strict control of the action parameter.

I hope this brief article helps you to make your applications a bit more secure.
1
Comment
Author:Bardobrave
  • 2
  • 2
4 Comments
LVL 19

Author Comment

by:Bardobrave
Since I wrote this article I've found more info on the matter and I've seen there is more danger than I initially thought. I'll try to find time to write a more exhaustive and clearer one on the dangers of blind model binding
0
LVL 75

Expert Comment

by:käµfm³d 👽
...a savvy user can alter the url of the form from something like...
I'm confused:  Are you saying that a savvy user could modify the URL on the client, or on the server? If the former, then how exactly does manually writing your own <form> tag mitigate this?

...however the exploit possibilities are far larger.
Such as?
0
LVL 19

Author Comment

by:Bardobrave
It's been some time since I wrote this, and almost had forgot about it. However, there's a real problem in the use of blind model binding, as anyone can use a tool to send petitions to server or just code manual petitions that attacks your model action sending different parameters.

If you had used UpdateModel without defining the parameters of your model that are public to editing, those malicious petitions could on the end pass the model binding and save to your database.

I'm not exactly sure what I mean two years ago about using manual forms instead of beginForm, however you must use the list of open parameters to UpdateModel to avoid any private data from being updated.
0
LVL 75

Expert Comment

by:käµfm³d 👽
Don't sweat it. I just stumbled across the article. I have been using MVC/Web API over the past couple of years, and I wanted to make sure I understood what you were presenting.
0

Featured Post

Exploring SQL Server 2016: Fundamentals

Learn the fundamentals of Microsoft SQL Server, a relational database management system that stores and retrieves data when requested by other software applications.

Join & Write a Comment

Learn how to collaborate with office 365 Office Online
Watch this simple and effective video tutorial to extract attachments from Outlook 2007 and try this easy method by yourself. No need to go anywhere, just watch the video and export attachments from Outlook in few simple steps. To know more, click h…

Keep in touch with Experts Exchange

Tech news and trends delivered to your inbox every month