什么是Mass Assignment(批量赋值)风险

一句话总结:批量赋值漏洞 ,指框架自动把外部传入的所有参数直接绑定到实体类/对象,攻击者借此篡改本不该被修改的敏感字段。


一、通俗理解

举个最常见场景:用户注册/修改个人资料接口

  1. 业务只允许用户修改:nicknameavatar
  2. 但数据库实体还有敏感字段:is_admin(是否管理员)、user_rolebalance(余额)、password
  3. 后端框架开启全字段自动绑定,前端传什么参数,就全部赋值给对象入库

攻击者请求时额外带上敏感参数

http 复制代码
POST /update-user
{
  "nickname": "test",
  "avatar": "xxx.jpg",
  "is_admin": true   // 恶意新增字段
}

后端没做过滤,直接执行更新 → 普通用户变成管理员,漏洞形成。


二、常见出现场景

主流 MVC/ORM 框架几乎都有这个特性,也是高危点:

  1. Java :Spring Boot @ModelAttribute、MyBatis-Plus 自动赋值、JPA
  2. Python:Django ORM、Flask-SQLAlchemy、Peewee
  3. PHP :Laravel $fillable/$guarded、ThinkPHP
  4. Node.js:Sequelize、Mongoose

典型代码示例(Python Flask + SQLAlchemy 危险写法)

python 复制代码
# 危险:直接把前端所有参数塞给用户对象
@app.route("/user/update", methods=["POST"])
def update_user():
    user = User.query.get(1)
    # 批量赋值,前端传啥改啥
    for k, v in request.form.items():
        setattr(user, k, v)
    db.session.commit()
    return "ok"

攻击者传 is_admin=1,直接提权。


三、危害等级

  • 越权提权:普通用户 → 管理员
  • 数据篡改:修改余额、权限、状态、密码
  • 越权操作:篡改他人数据、关闭账号等 属于 OWASP 常见高危漏洞

四、标准修复方案(按推荐优先级)

1. 白名单(最推荐,通用)

只允许指定字段赋值,拒绝所有未知参数。

python 复制代码
# 只允许这两个字段
allow_fields = ["nickname", "avatar"]
for k, v in request.form.items():
    if k in allow_fields:
        setattr(user, k, v)

2. 框架原生限制(框架专属)

Python Django

显式指定允许字段,禁止全量绑定:

python 复制代码
# 模型层面限制
class User(models.Model):
    nickname = models.CharField()
    is_admin = models.BooleanField(default=False)

# 视图/表单只接收指定字段
form = UserForm(request.POST)
if form.is_valid():
    form.save(commit=False)

PHP Laravel

  • $fillable白名单(允许批量赋值的字段)
  • $guarded = [] 是高危(允许所有字段)
php 复制代码
class User extends Model
{
    // 安全:仅允许这两个字段批量赋值
    protected $fillable = ['nickname', 'avatar'];
}

Java Spring Boot

使用 @DataBinder@InitBinder 排除敏感字段:

java 复制代码
@InitBinder
public void initBinder(DataBinder binder) {
    // 黑名单:禁止绑定敏感字段
    binder.setDisallowedFields("isAdmin", "userRole", "balance");
}

3. 使用 DTO/入参实体(企业项目标准做法)

接口只接收 DTO 对象,不和数据库实体直接绑定

  • 前端参数 → DTO(仅业务字段)→ 手动赋值给 DB 实体
  • 彻底隔离,从架构上杜绝批量赋值。

五、快速识别漏洞特征

  1. 接口直接使用数据库实体类接收前端参数
  2. 代码存在 setattr、循环遍历请求参数赋值
  3. 框架开启无限制批量绑定 (如 Laravel $guarded = []
  4. 接口未做字段过滤、未使用白名单

六、精简总结

  • 本质:外部可控参数 → 无过滤批量赋值到数据模型
  • 核心风险:篡改敏感字段、提权、越权
  • 最简修复字段白名单 / 单独使用入参 DTO,不要用数据库实体直接接收请求参数。
相关推荐
葫芦和十三14 小时前
图解 MongoDB 21|选举与 failover:Primary 是怎么选出来的
后端·mongodb·agent
GetcharZp15 小时前
26k Star 开源内网穿透神器 NetBird,一分钟实现全球设备互联!
后端
考虑考虑15 小时前
Mybatis实现批量插入
java·后端·mybatis
咖啡八杯16 小时前
GoF设计模式——中介者模式
java·后端·spring·设计模式
lizhongxuan18 小时前
多Agent之间的区别
后端
kyriewen20 小时前
我手写了一个 EventEmitter,面试官追问了 6 个问题——第 4 个我没答上来
前端·javascript·面试
杨充20 小时前
1.面向对象设计思想
后端
IT_陈寒20 小时前
Java的Date类又坑了我一次,改用时间戳真香
前端·人工智能·后端
systemPro21 小时前
2.6亿条设备数据,历史查询从超时到50ms,我做了什么
后端
要阿尔卑斯吗21 小时前
提示词优化启示:为什么“按顺序输出“比“关键度评分“更有效
后端