2017-04-22 106 views
2

首先考虑下面由ASP.NET Core MVC脚手架生成的代码片段。如何防止访问者篡改POST操作中的ID字段?

// 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(); 
    } 

问题

例如,访问者请求id=5在GET被删除,但后来他将其设置为一个号码与POST的id篡改如id=6或将其设置为无效值,如id=xodsfsdofsdfosdfsd。由于HttpPost没有初步检查,如何防止这种情况?

+0

其实我也想知道为什么脚手架默认不提供POST初步检查的原因。你知道吗? –

+0

在将Cookie加载到表单元素之前将值存储在cookie中,并使用发布的值对其进行验证。如果两者都相同,则继续前进,否则抛出错误。 –

+3

用户删除student_may或者可能没有授权删除学生。这取决于您的应用程序来决定。您可能希望在您的POST操作中添加一个检查来验证用户**,因为**您无法防止篡改值**。这不是一个脚手架工具可以为你决定的事情。 – Jasen

回答

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

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

让我们假设发送的ID是一个复选框或下拉列表中取。现在,如果用户更改该值,将会发生什么情况:

如果要修改数据库,首先需要检查的是数据是否与用户关联。如果不是,则出现其他情况:

  1. 用户有意篡改了id。那么,如果是这样的话,用户帐户必须被阻止,但是如何?支票号码2:

  2. 用户已注销并重新登录,但在不同的浏览器选项卡中使用不同的帐户。现在,发送请求的页面具有先前登录的帐户信息。

基本上,帐户信息是从身份验证Cookie检索和如果用户打开一个标签,并注销,并登录在不同的帐户,你需要找到一种方式来弄清楚。

这里有一些建议供您参考:

  • 使用SignalR或其他方式来刷新所有的浏览器选项卡,如果用户注销。这就是大多数知名公司的做法吸引谷歌或Facebook。

  • 如果您想使其更容易,请将验证cookie中保存的用户名或任何数据进行哈希处理,并将其保存在HTML代码的隐藏字段中。然后将它与从请求中检索到的cookie的散列值进行比较。如果它们发生冲突,请阻止用户采取任何操作并刷新页面。

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

1

那么,这是我的建议。

1-数据访问授权(这是您需要的) 在使用EF上下文删除用户之前,您需要验证登录的用户是否真的拥有学生记录。例如,在选择删除记录之前,您需要验证返回的学生对象是否具有与登录用户标识相同的用户标识(或其他名称)。这将禁止现有登录的应用程序用户篡改其他现有用户的数据。通常,每条记录必须拥有自己的所有者外键db字段。

2-使用GUID: 不要以这种方式共享您的主键学生ID。相反,请创建一个具有uniqueidentifier类型的StudentGUID db字段。这是您需要与浏览器共享的内容。这将禁止不良用户使用自动增量整数对服务器运行自动客户端代码。

3会话授权: 如果您使用的是asp.net Forms身份验证,那么它很容易将[Authorize]属性添加到您需要保护的mvc操作。这将确保只有登录的用户才能执行您的mvc操作代码。