This content originally appeared on DEV Community and was authored by Claude Fassinou
Laravel is a powerful PHP framework, and its Eloquent ORM makes database interactions a breeze. However, a common pitfall involving the $fillable property can lead to a critical security flaw known as a Mass Assignment Vulnerability, potentially compromising your entire application.
What is Mass Assignment?
Mass assignment is the practice of populating a model with an array of user input, usually from a form submission, in a single go. In Laravel, this often looks like:
// Populating a model with ALL request data
User::create(\$request->all()); // 👈 DANGER ZONE!
This is convenient, but it’s dangerous if you don’t control which attributes are allowed to be set this way.
The Role of \$fillable
The $fillable property in a Laravel model is your white-list for mass assignment. It specifies an array of columns that are safe to be filled using methods like create(), update(), or fill().
If an attribute is not in the $fillable array, Laravel’s security layer will prevent it from being set via mass assignment.
The Business Danger: Unrestricted Access
The image provided illustrates the exact danger:
-
Vulnerable Model: The
Usermodel has a sensitive column,is_admin, included in the$fillablearray.
// In User.php protected \$fillable = [ 'name', 'email', 'password', 'is_admin', // 👈 THE FLAW ]; -
Vulnerable Controller: The application blindly accepts and assigns all validated request data to the model.
// In TestController.php User::create(\$request->all());
A malicious user can simply inject an is_admin field into their registration form data. Because the controller uses create(\$request->all()) and is_admin is in $fillable, the application will happily set the user’s is_admin attribute to true (or 1).
The Result: A standard user can instantly become an Administrator, gaining unauthorized access to sensitive data, control panels, and potentially damaging your entire system and business integrity.
The Solution: Always Restrict \$fillable
To protect your business, always adhere to this simple rule:
NEVER include sensitive, high-privilege columns like is_admin, role, api_token, or balance in your model’s \$fillable property.
The Safe Code Fix:
-
Remove the sensitive field from
$fillable:
// The SECURE User.php protected \$fillable = [ 'name', 'email', 'password', // 'is_admin' is GONE! ✅ ]; -
Explicitly handle sensitive fields (if needed): If you need to set
is_adminor another protected field, do it explicitly, line by line, only after checking authorization.
// The SECURE Controller code \$validatedData = \$request->validate([...]); \$user = User::create(\$validatedData); // Set protected fields ONLY if an authorized admin is doing it. // e.g., if (auth()->user()->isAdmin()) { \$user->is_admin = 1; \$user->save(); }
Protect your application by being meticulous with your $fillable arrays!
I am Claude Fassinou, Software developer, and Code reviewer.
This content originally appeared on DEV Community and was authored by Claude Fassinou
The Result: A standard user can instantly become an Administrator, gaining unauthorized access to sensitive data, control panels, and potentially damaging your entire system and business integrity.