正如我在Can you spot the security implications/vulnerability of a small change to an ASP.NET MVC 3.0+ Model Binder?详细询问的那样,CartModelBinder类的一个版本(如下所示)允许通过MVC ModelBinding漏洞(也称为OverPosting)进行利用
你能发现哪一个吗?
理想情况下,您应该使用UnitTests提供答案/结果/证明:)
版本1:使用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
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;
}
}
控制器示例:
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 });
}
答案 0 :(得分: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 });
}
}