I am relatively new to Software Development using the Laravel framework and I keep seeing the $fillable property in model files. Could someone explain exactly what this attribute does and why it is necessary when saving data from a form? I am curious if there is a security risk in leaving it out, and what the difference is between using fillable versus the guarded property for database security.
3 answers
The $fillable attribute is a whitelist of database columns that can be "mass-assigned" using methods like create() or update(). In modern Software Development, users often send form data as an array. Without $fillable, a malicious user could inject extra fields into the HTTP request, such as is_admin=1. If you pass the entire request()->all() to your model, Laravel would update that column, potentially granting unauthorized access. By defining $fillable, you are explicitly telling Laravel which fields are safe to be updated in bulk, effectively ignoring any unexpected data sent by the client.
If I have a very large table with 50 columns, isn't it tedious to whitelist every single one? Is there a way to just blacklist the sensitive ones like 'id' or 'password' instead?
Keep in mind that if you are manually assigning values, like $user->is_admin = 1; $user->save();, the $fillable restrictions are completely ignored. It only applies to mass-assignment methods.
I agree with Catherine. It's an important distinction for Software Development. Eloquent assumes that if you are manually setting a property in your code, you know what you are doing and doesn't block you.
Marcus, that’s where the $guarded attribute comes in! While $fillable is a whitelist, $guarded acts as a blacklist. If you set protected $guarded = ['id', 'is_admin'];, then every other column is automatically mass-assignable. However, in professional Software Development, many teams prefer $fillable because it is "secure by default." If you add a new sensitive column to your database later but forget to add it to $guarded, you might accidentally leave a security hole. With $fillable, you have to intentionally grant access, which is much safer.