Laravel’s `fillable property` and the Hidden Danger to Your Business App



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:

  1. Vulnerable Model: The User model has a sensitive column, is_admin, included in the $fillable array.

    // In User.php
    protected \$fillable = [
        'name',
        'email',
        'password',
        'is_admin', // 👈 THE FLAW
    ];
    
  2. 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:

  1. Remove the sensitive field from $fillable:

    // The SECURE User.php
    protected \$fillable = [
        'name',
        'email',
        'password',
        // 'is_admin' is GONE! ✅
    ];
    
  2. Explicitly handle sensitive fields (if needed): If you need to set is_admin or 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