过多发布攻击(Over Posting):
黑客可使用 Fiddler 等工具或通过编写某个 JavaScript 来提交表单中不存在的字段值, 达到修改数据库的目的。
如何防范过多发布:
- 在表单Post请求处理方法中使用TryUpdateModelAsync 来更新数据库:
public async Task<IActionResult> OnPostAsync()
{
var emptyStudent = new Student();
if (await TryUpdateModelAsync<Student>(
emptyStudent,
"student", // Prefix for form value.
s => s.FirstMidName, s => s.LastName, s => s.EnrollmentDate))
{
_context.Students.Add(emptyStudent);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
return Page();}
代码创建一个空的Student 对象,然后使用发布的表单域更新 Student 对象的属性, 以此避免过多发布攻击。
TryUpdateModelAsync 方法:
- 仅更新指定的属性 (s => s.FirstMidName, s => s.LastName, s => s.EnrollmentDate)。
- 查找带有“student”前缀的表单值。 例如 Student.FirstMidName。 该自变量不区分大小写。
- 使用模型绑定系统将字符串中的表单值转换为 Student 模型中的类型。 例如,EnrollmentDate 必须转换为 DateTime。
- 采用专用的视图模型:
- 应用程序模型通常称为域模型。 域模型通常包含数据库中对应实体所需的全部属性。
- 视图模型只包含它所用于的 UI所需的属性。
[BindProperty]
public StudentVM StudentVM { get; set; }
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
var entry = _context.Add(new Student());
entry.CurrentValues.SetValues(StudentVM);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
SetValues 方法通过从视图模型对象读取值来设置域模型对象的值。 SetValues 使用属性名称匹配。 视图模型类型不需要与模型类型相关,它只需要具有匹配的属性。
相对来说, 第1种方法更简单灵活