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

Published on
9,789 Points
1 Endorsement
Last Modified:
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.
  • 2
  • 2
LVL 19

Author Comment

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
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?
LVL 19

Author Comment

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.
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.

Featured Post

Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

Join & Write a Comment

In response to a need for security and privacy, and to continue fostering an environment members can turn to for support, solutions, and education, Experts Exchange has created anonymous question capabilities. This new feature is available to our Pr…
When you have multiple client accounts to manage, it often feels like there aren’t enough hours in the day. With too many applications to juggle, you can’t focus on your clients, much less your growing to-do list. But that doesn’t have to be the cas…

Keep in touch with Experts Exchange

Tech news and trends delivered to your inbox every month