我有一个多用户ASP.NET MVC应用程序。用户不应该看到或对彼此的数据做任何事情。
我的一个控制器操作是强制POST到/编辑以编辑记录(例如联系人)。现在这是我的问题:如果有人伪造一个简单的POST到/ Edit(它会自动模型绑定到我的联系人类)并编辑其他人的信息怎么办?由于每个记录都由Id标识,所以必须做的就是使用Id XXX进行假POST,然后记录#XX将被攻击者提供的任何内容覆盖。我怎么能阻止这个?
我唯一想到的是每次从数据库中获取原始实例,检查它实际上是否在用户的可编辑对象范围内(他通常会看到的对象)编辑)并且仅当该检查通过以继续使用UpdateModel并提交更新更改时。
有更好的方法吗?
编辑:这不是跨站点/ CSRF攻击。另一个登录用户可以执行此操作。
答案 0 :(得分:4)
视图/页面的授权和特定对象的授权实际上是两个独立的概念。最好的方法是将Authorize属性与ASP.NET角色系统结合使用以授予或拒绝对给定页面的访问权限。一旦您确认用户有权访问该页面,您就可以验证他是否具有他正在请求其所请求对象的权限。我在我的应用程序中使用这种方法,效果很好。通过首先使用“授权”过滤器,它可以显着提高性能,因为实际的对象权限检查操作要大得多。
此外,我使用自制的规则系统来实际设置和确定用户是否有权访问该对象。例如,在我的系统中,管理员可以完全访问每个对象。 (这是一个规则。)创建对象的用户具有对对象的完全访问权限(也由规则指定)。此外,用户的经理可以完全访问其员工可以访问的所有内容(再次由规则指定)。然后,我的应用程序评估对象以查看是否适用任何规则 - 首先从最小的复杂规则开始,然后再移动最后的更复杂的规则。如果任何规则是肯定的,我将停止规则评估并退出该功能。
答案 1 :(得分:1)
您可以做的是使用以下语法排除模型绑定中的ID:
public ActionResult Edit([Bind(Exclude="Id")] User userToEdit)
然后从当前登录用户获取ID,这样只有登录用户可以编辑自己的项目而且没有其他人。
答案 2 :(得分:0)
首先加载原始记录并检查所有者听起来对我来说是一个好方法。或者,您可以添加一个包含记录ID的隐藏字段,并对该字段进行加密签名以确保无法更改,或者获取记录ID,使用用户ID作为盐对其进行哈希并检查(假设您正在使用)您应该使用提供者唯一ID,而不是登录名)
答案 3 :(得分:0)
这个问题让我想起了一篇文章,其中涵盖了我收藏的类似问题(根据URL操纵攻击)。它们处理经过身份验证的用户,弄乱了另一个用户的数据。您可能会发现它很有用: link text
编辑:此链接应该是正确的: Prevent URL manipulation attacks