Mass assignment là việc gán thẳng toàn bộ body request vào object nghiệp vụ.
Nếu model có trường nhạy cảm mà endpoint không lọc, client tự thêm trường đó vào JSON là tự nâng quyền:
// Endpoint intended for name/avatar only
app.patch('/api/me', async (req, res) => {
await User.update(req.body, { where: { id: req.user.id } }) // vulnerable
}){ "name": "An", "role": "admin", "emailVerified": true, "balance": 999999 }Một request là đủ. Biến thể hay gặp khác: isActive, organizationId (chuyển mình sang tổ chức khác), userId trong tài nguyên con để gán bản ghi cho người khác, và ở luồng đăng ký thì createdAt/plan. OWASP xếp đây vào API3 — Broken Object Property Level Authorization.
Cách chặn, theo thứ tự hiệu quả:
1. Danh sách cho phép tường minh (allowlist), không dùng danh sách chặn. Chỉ trích đúng các trường mong đợi rồi mới ghi:
const { name, avatarUrl } = req.body
await User.update({ name, avatarUrl }, { where: { id: req.user.id } })2. DTO / schema đầu vào riêng cho từng endpoint (zod, class-validator...) với chế độ strip hoặc từ chối trường lạ — đừng dùng chung một type với entity DB.
3. Tách model đọc và model ghi. Trường chỉ hệ thống được đặt (role, status, balance) không nằm trong bất kỳ input type nào; muốn đổi thì đi qua endpoint riêng có kiểm tra quyền.
4. Kiểm ở tầng ORM nếu framework hỗ trợ: fillable/guarded (Laravel), attributes cho update (Sequelize), select tường minh (Prisma).
5. Kiểm thử: gửi thêm trường thừa vào mỗi endpoint ghi và khẳng định nó bị bỏ qua hoặc bị từ chối.
Lưu ý phần response cũng cùng lỗi ngược lại: trả nguyên entity ra ngoài sẽ rò passwordHash, internalNotes. Serialize qua DTO cả hai chiều.