You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET MVC中使用ViewModel时,Edit控制器仍易遭过度提交?如何防范?

关于ViewModel过度提交修改非目标dbModel的疑问与解决方案

你提的这个问题非常关键——是的,这种情况完全有可能发生,而且是过度提交攻击里很典型的一种场景,我来给你拆解清楚:

为什么会有风险?

虽然你在代码里没有手动把viewModel.Id绑定到dbModel上,但ASP.NET的默认模型绑定机制会自动解析请求中的所有参数,包括攻击者恶意构造的Id值,把它填充到viewModel.Id里。接下来你用db.Models.Find(viewModel.Id)去查询数据库,这就等于把控制权交给了攻击者——他们只要在请求里把Id改成任意存在的值,你的代码就会修改那个对应的数据,完全偏离了原本要修改的目标记录。

几个简单有效的防范方法

  • 从可信来源获取Id:不要依赖ViewModel里的Id,而是从路由参数、当前登录用户的关联数据这类攻击者无法篡改的地方获取。比如把Action改成接收路由里的Id:

    [HttpPost]
    public ActionResult Edit(int id, ViewModel viewModel)
    

    之后用这个id去查询dbModel,完全忽略viewModel.Id,从根源上切断攻击者的篡改路径。

  • 使用绑定白名单:在ViewModel参数上添加[Bind]特性,明确指定允许绑定的属性,直接排除Id。比如:

    public ActionResult Edit([Bind(Include = "Name,Description")] ViewModel viewModel)
    

    这样模型绑定只会处理你指定的属性,请求里的Id参数会被直接忽略,viewModel.Id不会被赋值。

  • 创建专用的更新ViewModel:干脆新建一个只包含需要修改的属性的ViewModel,完全去掉Id字段。比如:

    public class UpdateModelViewModel
    {
        public string Name { get; set; }
        public string Description { get; set; }
    }
    

    这样不管攻击者怎么构造请求,都没有Id字段可以提交,彻底消除这个风险。

修改后的示例代码(用路由Id的方式)

[HttpPost]
public ActionResult Edit(int id, ViewModel viewModel)
{
    if (ModelState.IsValid)
    {
        var dbModel = db.Models.Find(id);
        if (dbModel == null)
        {
            return NotFound();
        }
        // 只绑定需要更新的属性
        dbModel.Name = viewModel.Name;
        dbModel.Description = viewModel.Description;
        
        db.Entry(dbModel).State = EntityState.Modified;
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(viewModel);
}

内容的提问来源于stack exchange,提问作者justiceorjustus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:07:08