---
title: Define $fillable — Never Use $guarded = []
impact: CRITICAL
impactDescription: disabling mass assignment protection allows attackers to write arbitrary model fields via crafted HTTP requests
tags: mass-assignment, fillable, guarded, security, eloquent, laravel
---

## Define $fillable — Never Use $guarded = []

Mass assignment attacks occur when a user passes unexpected fields (e.g. `is_admin=1`) that get written to the database. `$guarded = []` disables all protection.

**Wrong:**

```php
class User extends Model
{
    protected $guarded = []; // All fields writable — DANGEROUS

    // Or: no $fillable defined at all (same effect with $guarded=[])
}

// Attacker sends: POST /users { "name": "Bob", "is_admin": 1 }
User::create($request->all()); // is_admin gets written!
```

**Correct:**

```php
class User extends Model
{
    // Explicit allowlist
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    // Fields like is_admin, email_verified_at are NOT here
    // They are set explicitly:
}

// Controller
User::create($request->validated()); // only validated+fillable fields written

// When you must set a guarded field, use direct assignment:
$user = new User($request->validated());
$user->is_admin = false; // explicit, intentional
$user->save();
```

**Also:** use `$request->validated()` not `$request->all()` so only schema-declared fields reach the model.
