Give mass assignment only the fields an operation may change
An account settings form shows a display name, but the request also includes is_admin=1. Updating the model from every request field can turn a small settings screen into an unintended privilege editor.
Limit the payload at the operation boundary
$data = $request->validate([
'display_name' => ['required', 'string', 'max:100'],
]);
$request->user()->update($data);
The model must also have an appropriate fillable or guarded configuration. Those protections complement request validation. A model used by several operations cannot always express each operation's narrower permissions through one global fillable list.
Set protected values from trusted context
For tenant-owned records, assign ownership from the current tenant relationship or explicit server-side context. Avoid accepting a hidden form input as evidence of ownership. A hidden input is just another editable request value.
Nested arrays need explicit allowed keys as well. A parent array rule alone is not a promise that every nested field is safe to persist. Map complex input to the intended structure when the request and storage models differ.
Test the normal update and a payload containing extra sensitive keys. Assert those keys remain unchanged in storage. Also test a legitimate administrative operation separately so tighter protections do not accidentally block the intended workflow. If a developer disables mass-assignment protection to solve a failing test, revisit the payload mapping first; the failure may be revealing an overly broad update rather than an inconvenient framework rule.