Securing Laravel

Securing Laravel

Share this post

Securing Laravel
Securing Laravel
In Depth: Mass-Assignment Vulnerabilities

In Depth: Mass-Assignment Vulnerabilities

[InDepth#15] There is a false confidence about mass-assignment vulnerabilities that hides how easy it is for them to occur and be exploited...

Stephen Rees-Carter's avatar
Stephen Rees-Carter
Apr 15, 2023
∙ Paid
1
Share

Greetings my friends! Last week we started our new series on the Top 10 security issues I’ve found during audits. Here’s the list so far:

#10 → Insufficient Input Validation
#9 → Missing Subresource Integrity (SRI)

As it turns out, we’ve covered SRI back in January 2022, so head over to Security Tip #14: Subresource Integrity to learn more about it. So rather than rehashing an old topic, this week we’re going to focus on another aspect of Insufficient Input Validation, specifically Mass-Assignment Vulnerabilities. This is a topic which is easily misunderstood and there is a false confidence that hides how easy it is for them to occur and be exploited…

But before we get into our topic, I want to briefly mention Substack Notes, which is a new space for us to share content, ideas, links, and generally do other social media-y type stuff. It looks cool, and I’m posting my Top 10 up there (#10, #9, #8, #7), plus other things, but there are also some big questions about moderation that the Substack team needs to answer. This is something I’m working through, and I’ll keep you updated.

👉 Security Audits: Worried about my Top 10 Laravel security issues? Book a security audit and make sure you’re covered! 🕵️

Looking to learn more?
⏩ Security Tip #28: Composer Audit
▶️ In Depth #11: Insecure Direct Object References (IDOR

Please consider becoming a paid subscriber to support Laravel Security in Depth.
You’ll receive weekly security tips and monthly In Depth articles, covering every aspect of building secure applications in Laravel.

Mass-Assignment Vulnerabilities

When you think of Mass-Assignment vulnerabilities on Laravel, I guarantee you’ll immediately think of the humble `$fillable` Eloquent property. That’s definitely what the Laravel Docs teach you…

If you’re not familiar with the `$fillable` Eloquent property, this is how it works:

First, you define the property on your model:

class User extends Model
{
    protected $fillable = ['name', 'email'];
}

Next, when creating or updating the model, only the allowed attributes can be filled.

$input = [
    'name'  => 'Bilbo Baggins',
    'email' => 'bilbo@example.com',
    'admin' => true
];

$user = User::create($input);

// $user->name  -> 'Bilbo Baggins'
// $user->email -> 'bilbo@example.com'
// $user->admin -> false

In the above example, the `admin = true` flag is ignored when creating the `User` model, protecting against a mass-assignment exploit to escalate the privileges of the newly created user.

And this is where many people stop learning about mass-assignment vulnerabilities and assume they are covered.

But are they?

I would argue that `$fillable` is the lesser, or possibly even optional, protection against mass-assignment. Great to use if you can, but not essential and definitely not my first choice.

In fact, I often allow mass-assignment across all fields of a Model using `$guarded = [];`, or even `Model::unguard()` across the entire app in `AppServiceProvider`. As controversial as that may be, I find `$fillable` gets in my way more often than it protects me. Disabling the protection actually makes the code cleaner and more maintainable.

So what do I do instead?

Keep reading with a 7-day free trial

Subscribe to Securing Laravel to keep reading this post and get 7 days of free access to the full post archives.

Already a paid subscriber? Sign in
© 2025 Stephen Rees-Carter
Privacy ∙ Terms ∙ Collection notice
Start writingGet the app
Substack is the home for great culture

Share