【问题标题】:Form security in MVC RazorMVC Razor 中的表单安全性
【发布时间】:2015-10-12 10:26:03
【问题描述】:

我的项目 MVC razor C# 中有 2 个表单

View1:显示所有记录。单击特定记录即可 编辑页面。

View2:以表格形式显示所选记录以供更新。

因此,当用户提交表单时...转到 Controller...Controller Action 方法有一个 View Model 参数,该参数具有从 View 中的隐藏字段填充的 ID 属性。

有人通过浏览器的 Inspect Element 故意更改 html 中的 ID 并且数据可能会转到错误的记录。

解决此问题的一种方法是从视图模型传递加密值。但是用户仍然可以从另一条记录中交换加密值,并可以在提交表单之前通过 Inspect Element 将该加密 ID 值放入 html 中的另一条记录中。

我希望我澄清了这个问题。阅读时仍有任何问题,请让我知道再次澄清。

请提出解决方案。

【问题讨论】:

  • view1 上是否有任何形式的授权?即用户是否能够编辑任何记录,或者他们是否只显示他们能够编辑的记录列表?
  • 如果是客户端,您应该将 ID 属性保留在会话或服务器端 cookie 中。
  • 加密不会有帮助。请参阅this answer,了解一种防止恶意用户更改隐藏输入值的技术。
  • @AmitSoni:真的吗?没有冒犯,但这绝对是错误的。首先,没有“服务器端cookies”之类的东西。 cookie 本质上是客户端的。其次,在你可能处理这种情况的所有方法中,在 session 中存储一个 id 值甚至都不会出现在列表中。
  • 对不起,不。您和您的朋友可能有共同的俗语,但没有“服务器端 cookie”之类的东西。有 cookie 和会话。

标签: c# asp.net-mvc-3 asp.net-mvc-4 c#-4.0 razor


【解决方案1】:

处理此问题的最佳方法是发布 id。相反,让 id 成为 URL 的一部分,然后如果它被改变,一个完全不同的资源正在发挥作用:

[HttpPost]
public ActionResult Edit(int id, Foo model)
{
    var foo = db.Foos.Find(id);
    if (foo == null)
    {
        return new HttpNotFoundResult();
    }

    if (ModelState.IsValid)
    {
        // map values from model (posted data) to instance from DB
        db.Entry(foo).State = EntityState.Modified;
        db.SaveChanges();
    }

    return View(model);
}

【讨论】:

  • 这篇文章有一个混淆之处。假设 ID = 1 的记录将被更新。但用户通过浏览器的 Inspect Element 故意在 html 中设置 ID = 3。因此,ID 在 Post Action 方法中永远不会为空。但我只想更新 ID = 1。我怎样才能确定?
  • 这就是重点。用户在表单中设置什么并不重要,因为唯一会更改的是 URL 中的 id。您完全忽略了ID 的任何提交值;你甚至不需要隐藏的输入。
  • 只有一个需要注意的陷阱 - 如果模型属性名为 ID(与参数相同)并且包含隐藏输入,并且恶意用户对其进行了更改,那么该参数将是更改后的值(DefaultModelBinder 在路由值之前从表单数据中读取值)所以最好不要包含任何隐藏的输入。
  • 在这种情况下,如何将值从 View 发布到 Controller ?
  • 你不需要,事实上不应该。这才是重点。当您编辑现有实体时,id 甚至不应该出现在表单上。它不应该被改变,所以不要提供一个向量来改变它。
猜你喜欢
  • 2012-09-19
  • 1970-01-01
  • 1970-01-01
  • 2012-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多