Wednesday, October 17, 2012

Mass Assignment Vulnerability in ASP.NET MVC

By now you may have seen what happened to github last night. In case you didn’t, let me bring you up to speed.
In a Ruby on Rails application, you can make a call to update your model directly from request parameters. Once you’ve loaded an ActiveRecord model into memory, you can poke its values by calling update_attributes and passing in the request parameters. This is bad because sometimes your model might have properties which you don’t want to be updated by just anyone. In a rails application, you can protect this by adding attr_accessible to your model and explicitly stating which properties can be updated via mass assignment.
I’m not going to pretend to be a Ruby dev and try to explain this with a Rails example. Github already linked to this fantastic post on the subject regarding Rails here. What I’m here to tell you is that this situation exists in ASP.NET MVC also. If you aren’t careful, you too could end up with a visit from Bender in the future.
So, let’s see this vulnerability in action on an ASP.NET MVC project.
First, let’s set up a model:
public class User {
    public int Id { get; set; }
    public string UserName { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public bool IsAdmin { get; set; }
}
Then let’s scaffold out a controller to edit this user:
public class UserController : Controller {
    IUserRepository _userRepository;
    public UserController(IUserRepository userRepository) {
        _userRepository = userRepository;
    }

    public ActionResult Edit(int id) {
        var user = _userRepository.GetUserById(id);
        return View(user);
    }

    [HttpPost]
    public ActionResult Edit(int id, FormCollection collection) {
        try {
            var user = _userRepository.GetUserById(id);
            UpdateModel(user);
            _userRepository.SaveUser(user);
            return RedirectToAction("Index");
        } catch {
            return View();
        }
    }
}
Do you see that UpdateModel call in the POST to ‘/User/Edit’. Pay attention to that. It looks innocent enough, but we’ll see in a minute why that is bad.
Next, we scaffold up a view and remove the checkbox that allows us to update the user’s Admin status. Once we’re done, it looks like this:
That works. We can ship it, right? Nope. Look what happens when we doctor up the URL by adding a query parameter:
I bet you guess what’s about to happen now. Here, I’ll break execution right at the problematic line so you can watch the carnage:
Okay, you can see the current values to the right. We’ve loaded user #42 from the database and we’re about to update all of his values based on the incoming request. Step to the next line and we see this:
UH OH. That’s not good at all. User #42 is now an administrator. All it takes is an industrious user guessing the names of properties on your entities for you to get burned here.
So, what can we do to prevent it? One way would be to change the way we call UpdateModel. You can use the overload which allows you to pass in an array of properties you want to include. That looks like this:
UpdateModel(user,new[]{"FirstName","LastName","Email"});
We’ve just created a whitelist of properties we will allow to be updated. That works, but it’s ugly and would become unmanageable for a large entity. Aesthetics aside, using this method isn’t secure by default. The developer has to actively do something here to be safe. It should be the other way around, it should be hard to fail and easy to succeed. The Pit of Success is what we want.
So, what can we really do to prevent it? The approach I typically take is to model bind to an object with only the properties I’m willing to accept. After I’ve validated that the input is well formed, I use AutoMapper to apply that to my entities. There are other ways to achieve what we want too, but I don’t have time to enumerate all of the scenarios.
Wrapping up
The point of all of this is that you need to understand exactly what your framework is doing for you. Just because there is a gun available, it doesn’t mean you have to shoot it. Remember folks, frameworks don’t kill people; developers with frameworks kill people. Stay safe out there friends, it’s a crazy world.

1 comment:

  1. Cảm ơn vi một bài viết xuất sắc. Mình cũng muốn giới thiệu về một thương hiệu dịch thuật uy tín: Công ty CP dịch thuật miền trung - MIDtrans địa chỉ 02 Hoàng Diệu, TP Đồng Hới, tỉnh Quảng Bình có Giấy phép kinh doanh số 3101023866 cấp ngày 9/12/2016 là đơn vị chuyên cung cấp dịch vụ dịch thuật, phiên dịch dành các cá nhân. Hệ thống thương hiệu và các Công ty dịch thuật con trực thuộc: công ty dịch thuật sài gòn 247 địa chỉ 47 Điện Biên Phủ, Phường Đakao, Quận 1 TP HCM, dịch thuật bình dương : địa chỉ 123 , Lê trọng tấn, dĩ an, bình dương là nhà cung ứng dịch vụ dịch thuật uy tín hàng đầu tại bình dương viet translate : dịch vụ dịch thuật cho người nước ngoài có nhu cầu, giao diện tiếng Anh dễ sử dụng; dịch thuật công chứng quận 6 (sáu) : nhà cung ứng dịch vụ dịch vụ dịch thuật phiên dịch hàng đầu tại Quận 6, TP HCM; công ty dịch thuật Đà Nẵng : Địa chỉ 54 Đinh Tiên Hoàng, Quận Hải Châu, TP Đà Nẵng chuyên cung cấp dịch vụ dịch thuật công chứng, dịch thuật chuyên ngành tại Đà Nẵng. Chúng tôi chuyên cung cấp các dịch vụ biên dịch và phiên dịch, dịch thuật công chứng chất lượng cao hơn 50 ngôn ngữ khác nhau như tiếng Anh, Nhật, Hàn, Trung, Pháp, Đức, Nga, Tây Ban Nha, Bồ Đào Nha, Ý, Ba Lan, Phần Lan, Thái Lan, Hà Lan, Rumani, Lào, Campuchia, Philippin, Indonesia, La Tinh, Thụy Điển, Malaysia, Thổ Nhĩ Kỳ..vv... Dịch thuật MIDtrans tự hào với đội ngũ lãnh đạo với niềm đam mê, khát khao vươn tầm cao trong lĩnh vực dịch thuật, đội ngũ nhân sự cống hiến và luôn sẵn sàng cháy hết mình. Chúng tôi phục vụ từ sự tậm tâm và cố gắng từ trái tim những người dịch giả.Tự hào là công ty cung cấp dịch thuật chuyên ngành hàng đầu với các đối tác lớn tại Việt nam trong các chuyên ngành hẹp như: y dược (bao gồm bệnh lý), xây dựng (kiến trúc), hóa chất, thủy nhiệt điện, ngân hàng, tài chính, kế toán. Các dự án đã triển khai của Công ty dịch thuật chuyên nghiệp MIDtrans đều được Khách hàng đánh giá cao và đạt được sự tín nhiệm về chất lượng biên phiên dịch đặc biệt đối với dịch hồ sơ thầu , dịch thuật tài liệu tài chính ngân hàng, dịch thuật tài liệu y khoa đa ngữ chuyên sâu. Đó là kết quả của một hệ thống quản lý chất lượng dịch thuật chuyên nghiệp, những tâm huyết và kinh nghiệm biên phiên dịch nhiều năm của đội ngũ dịch giả của chúng tôi. Hotline: 0947688883. email: info@dichthuatmientrung.com.vn . Các bạn ghé thăm site ủng hộ nhé. Cám ơn nhiều

    ReplyDelete