Масове призначення (mass assignment) - коли API бере тіло запиту й записує його в модель цілком. Клієнт додає поле, якого форма не має, - і змінює те, що не повинен.
// небезпечно
$user->update($request->all());
PATCH /api/profile
{"name": "Оля", "is_admin": true, "balance": 1000000}
Дзеркальна проблема - зайві дані у відповіді: return $user; віддає всі атрибути моделі, включно з тими, що клієнту бачити не можна (внутрішні прапорці, хеші, токени, приховані поля інших користувачів). OWASP об'єднує обидві проблеми в категорію «порушена авторизація на рівні властивостей об'єкта».
Захист на вході:
// лише перевірені поля
$validated = $request->validate([
'name' => ['required', 'string', 'max:255'],
'bio' => ['nullable', 'string', 'max:1000'],
]);
$user->update($validated);
validate()/ Form Request повертає лише ті поля, для яких є правила, - решта ігнорується;$fillableу моделі - друга лінія захисту: навітьupdate($request->all())не запише поля поза списком.$guarded = []вимикає цей захист;- поля, залежні від прав (роль, статус модерації), - окремі ендпойнти чи явні перевірки: «змінювати
roleможе лише адміністратор».
Захист на виході:
return new UserResource($user); // явний перелік полів
- API Resource чи DTO з явним переліком полів замість серіалізації моделі;
$hiddenу моделі (паролі, токени) - корисно, але недостатньо: краще відповідь описувати явно;- поля за правами:
'email' => $this->when($request->user()->can('viewContacts', $this->resource), $this->email).
Ознаки проблеми під час рев'ю коду:
$request->all()чи$request->input()без валідації, передане вcreate/update;return $modelабо$model->toArray()у контролерах API;$guarded = []у моделях, що змінюються через API.
Тест, що варто мати: відправити зайве поле (is_admin: true) і перевірити, що воно не змінилося.
Докладніше в документації: OWASP API3:2023 - авторизація на рівні властивостей