如何防止访问者在POST操作中篡改id字段?

时间:2017-04-22 20:46:18

标签: c# asp.net asp.net-mvc

首先考虑ASP.NET Core MVC脚手架生成的以下代码片段。

// GET: Students/Delete/5
public async Task<IActionResult> Delete(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var student = await _context.Students
        .SingleOrDefaultAsync(m => m.ID == id);

    if (student == null)
    {
        return NotFound();
    }

    return View(student);
}

// POST: Students/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
    var student = await _context.Students.SingleOrDefaultAsync(m => m.ID == id);
    _context.Students.Remove(student);
    await _context.SaveChangesAsync();
    return RedirectToAction("Index");
}

HttpGetHttpPost操作方法存在以下差异:

  • id在“获取”中可以为空,但在“帖子”中不可为空。
  • 以下初步检查仅限于Get。

代码:

    if (id == null)
    {
        return NotFound();
    }

    var student = await _context.Students
                .SingleOrDefaultAsync(m => m.ID == id);

    if (student == null)
    {
       return NotFound();
    }

问题

例如,要在GET中删除访问者请求id=5,但稍后他会通过将id设置为id=6或将其设置为id=xodsfsdofsdfosdfsd来篡改POST中的HttpPost无效值,例如onBackPressed()。由于SearchView中没有初步检查,如何防止这种情况?

2 个答案:

答案 0 :(得分:2)

您可能希望在POST操作中添加一项检查以验证用户,因为you cannot prevent tampering with the value

删除学生的用户可能有也可能没有删除学生的权限。这取决于您的申请决定。这不是脚手架工具可以为您决定的。

[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
    var authorized = ValidateStudentDeletion(User, studentId: id);

    if (authorized)
    {
        // delete student
        ...
        return RedirectToAction("Index");
    }
}

答案 1 :(得分:1)

我一直在处理这个问题很长一段时间,在审阅了一些文章之后,我的结论是:

我们假设发送的ID来自复选框或下拉列表。现在,如果用户更改了值,会发生什么:

如果要修改数据库,首先需要检查的是数据是否与用户相关联。如果没有,这里有其他情况:

  1. 用户故意篡改了ID。那么,如果是这样的话,必须阻止用户帐户,但如何?检查2号:

  2. 用户已注销并再次登录,但在其他浏览器标签中使用其他帐户。现在,发送请求的页面具有先前登录的帐户信息。

  3. 基本上,帐户信息是从身份验证Cookie中检索的,如果用户打开标签并注销并使用其他帐户登录,则需要找到一种方法来解决问题。

    以下是一些建议:

    • 如果用户退出,请使用SignalR或其他方式刷新所有浏览器选项卡。这是大多数知名公司的做法,就像Google或Facebook一样。

    • 如果您想更轻松,请将用户名或您在身份验证Cookie中保存的任何数据哈希,并将其保存在HTML代码的隐藏字段中。然后将其与从请求中检索到的cookie的相同哈希值进行比较。如果他们确实发生冲突,请阻止用户采取任何操作并刷新页面。

    我通常做的是在数据库中保存这些冲突,如果超出限制,我意识到用户是垃圾!