Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

In ASP.NET MVC, when I perform a HTTP post to /controller/action/UserID ...

and have a corresponding route /controller/action/{UserID} ...

and if I do a Form POST, the POSTed data UserID overwrites anything that the route was originally says. (at least it does in ASP.NET MVC4)

To me this says a few things:

  • Don't trust the URL... since POSTed data may hide what is really going on.
  • Anyone who can guess the route variable names in ASP.NET MVC, can put unexpected data into a controller

  • ....?

Questions

  • Is this behavior consistent across other MVC frameworks (Rails etc)?
  • What are some ways to guard against this type of unexpected results? Should every POST be cross checked with URL parameters?
share|improve this question

1 Answer 1

Don't trust the URL... since POSTed data may hide what is really going on.

The URL should be treated as a client-side value and should not be trusted anyway. Anyone can easily alter the URL and could easily create a POST to any UserID.

Anyone who can guess the route variable names in ASP.NET MVC, can put unexpected data into a controller

This can happen anyway by parameter tampering. There are some useful pointers in this guide: http://msdn.microsoft.com/en-us/magazine/hh580736.aspx

Specifically

What Is It? Parameter tampering is an attack in which parameters are altered in order to change the application’s expected functionality. The parameters may be on a form, query string, cookies, database and so on. I’ll discuss attacks involving Web-based parameters.

How Is It Exploited? An attacker alters parameters to trick the application into performing an action it wasn’t intending. Suppose you save a user’s record by reading her user ID from the query string. Is this safe? No. An attacker can tamper with a URL in your application

In MVC this can happen via Model Binding:

Model binding is a great feature of Model-View-Controller (MVC) that helps with parameter checks as the properties on the Order object will automatically be populated and converted to their defined types based on the form information. ... Just be careful to limit what properties you allow to be populated and, again, don’t trust the page data for important items. ...

Note that I use the [Bind(Exclude)] attrib­ute here to limit what MVC is binding into my Model in order to control what I do or don’t trust. This ensures the UserId won’t come from the form data and thus can’t be tampered with.

So you should also be careful that form parameters that don't exist in your view cannot be tampered and added by a malicious user. You would do this by adding the Exclude attribute:

public ActionResult Edit([Bind(Exclude="UserId")] Order order)

Is this behavior consistent across other MVC frameworks (Rails etc)?

Not sure, but I don't see it as a flaw as permission checks should be made on POSTs as well as your GETs. You application should not assume that a URL that has been POSTed to has permission to do this just because that of the false assertion that the URL with the form on must have been loaded first.

What are some ways to guard against this type of unexpected results? Should every POST be cross checked with URL parameters?

You code should just decide to take either the route variable or the POST variable (if it's provided to you from MVC as a method variable named UserID then why not use that, it doesn't matter if it was from POST data or the URL as long as you are consistent), and then make all logic decisions based on that. This includes the initial authorisation and also the processing and business logic - they should all use the same origin of the value to make sure actions are only carried out when authorised.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.