ASP.Net MVC 重复提交

威胁概述

ASP.Net模型绑定通过重复提交成为了另外一种攻击媒介,例如:

我们有一个允许用户提交评价意见的商店商品页面:

public class Review{
	public int ReviewID {get;set;}
	public int ProductID {get;set;}
	public Product Product {get;set;}
	public string Name {get;set;}
	public string Comment {get;set;}
	public bool Approved {get;set;}
}

我们想向用户展示一个简单的表单,其中只包含字段Name和Comment:

Name:@Html.TextBox("Name")

Comment:@Html.TextBox("Comment")

我们不希望用户自己能够审核通过自己的评论,然而有大量Web工具可以恶意的向表单添加"Approved=true"。

然而模型绑定器并不知道提交的表单包含哪些字段,并且还会将Approved属性设置为true。

更糟糕的是Review类当中还有一个Product属性,因此还可能会更改掉Product.Price的字段值,这样可能会改变表中的一些值,这些值的修改最终超出了用户的权限。

防范

  • 使用Bind特性防御重复提交攻击

Bind特性可用于控制器也可以用户控制器操作参数当中,可以白名单来指定允许绑定的字段,例如:
[Bind(Include="Name,Comment")]
也可以使用黑名单,例如:
[Bind(Exclute="ReviewID,ProductID,Product,Approved")]

诚然使用白名单的方法更加简单安全。