2013-07-18 157 views
1

創建爲我詳細的CartModelBinder類(如下圖所示)的版本Can you spot the security implications/vulnerability of a small change to an ASP.NET MVC 3.0+ Model Binder?一個問安全漏洞允許開發通過MVC ModelBinding漏洞(也稱爲OverPosting)通過ASP.NET MVC模型綁定器

你能找出哪些一?使用DefaultModelBinder和CreateModel

public class CartModelBinder : DefaultModelBinder 
{ 
    private const string sessionKey = "Cart"; 

    protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) 
    { 
     // get the Cart from the session 
     Cart cart = (Cart)controllerContext.HttpContext.Session[sessionKey]; 
     // create the Cart if there wasn't one in the session data 
     if (cart == null) 
     { 
      cart = new Cart(); 
      controllerContext.HttpContext.Session[sessionKey] = cart; 
     } 
     // return the cart 
     return cart; 
    } 
} 

版本2:使用IModelBinder和BindModel

理想情況下,你應該使用單元測試:)

1版提供你的答案/結果/證據

public class CartModelBinder : IModelBinder { private const string sessionKey = "Cart"; public object BindModel(ControllerContext controllerContext,ModelBindingContext bindingContext) { // get the Cart from the session Cart cart = (Cart)controllerContext.HttpContext.Session[sessionKey]; // create the Cart if there wasn't one in the session data if (cart == null) { cart = new Cart(); controllerContext.HttpContext.Session[sessionKey] = cart; } // return the cart return cart; } } 

Co ntroller示例:

public RedirectToRouteResult AddToCart(Cart cart, int productId, string returnUrl) 
{ 
    Product product = repository.Products 
     .FirstOrDefault(p => p.ProductID == productId); 

    if (product != null) 
    { 
     cart.AddItem(product, 1); 
    } 
    return RedirectToAction("Index", new { returnUrl }); 
} 
+1

第二個版本僅從會話中返回購物車。第一個版本可以從發佈數據中返回購物車。 – Kyle

+0

是的,這不是一件好事嗎? –

+1

是在這個例子中,因爲可以通過發佈不同的購物車來編輯產品和價格。也許這個具體的例子是人爲的,但是如果你不希望數據發佈,你爲什麼會接受一個購物車作爲參數。這只是爲了從會話中獲得一個項目而造成的大量混淆。這是你真正的錯誤。 – Kyle

回答

1

您目前的設計很容易被誤用,就像您建議的那樣。更好的解決方案是最初購買購物車並使用該實例。

public class CartController : Controller 
    { 
     private IProductRepository repository; 
     private IOrderProcessor orderProcessor; 
     private cart; 
     public CartController(IProductRepository repo, IOrderProcessor proc) 
     { 
      repository = repo; 
      orderProcessor = proc; 
      cart = Session["Cart"]; // or Cart.Current 
     } 

     public RedirectToRouteResult AddToCart(int productId, string returnUrl) 
     { 
      Product product = repository.Products 
       .FirstOrDefault(p => p.ProductID == productId); 

      if (product != null) 
      { 
       cart.AddItem(product, 1); 
      } 
      return RedirectToAction("Index", new { returnUrl }); 
     } 

    }