26
3 Ways to Mitigate Mass Assignment Vulnerabilities in Laravel
Ep#22@Laracasts: 3 Ways to Mitigate Mass Assignment Vulnerabilities in Laravel
This post is a part of the Week X of 100DaysOfCode Laravel Challenge series.
What is Mass Assignment?
Mass Assignment in Laravel refers to assigning values to model attributes in bulk, in the form of an array ["title" => "ttl", "slug" => "slg", "excerpt" => "exrpt", "body" => "bdy"]
, in the create()
, update()
or fill()
methods.
Mass Assignment Vulnerability:
A malicious user can pass a field in an HTTP request that can unexpectedly alter value in your database table column. For example, a user can renew his/her subscription or change their user role to admin.
How does Laravel deal with Mass Assignment Vulnerability:
Laravel, by default, does not support mass assignment to protect you from the vulnerability. If you try doing so, Laravel will throw a MassAssigmentException
error.
Post::create(['title' => "my new blog post", 'slug' => "my-new-blog-post"]);
will throw the exception as:
Illuminate\Database\Eloquent\MassAssignmentException with message 'Add [title] to fillable property to allow mass assignment on [App\Models\Post].'
How to allow Mass Assignment in Laravel:
As Laravel doesn't support Mass assignment by default. So, if you need it, you can allow it in three different ways.
1) By mentioning the Mass assignable field explicitly in the Model's $fillable
property, like this
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
protected $fillable = ["title"];
}
2) By guarding only one or some specific fields and allowing the rest to be Mass assignable. Like this
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
protected $guarded = ["id"]; // Guard only id and allow the rest to be Mass Assignable
}
3) By disabling the Mass Assignment Protection at all
You can disable the default Mass Assignment protection at all by setting the Model's $guarded property to an empty array. And this is the riskiest part. You should never ever pass user-supplied input in the mass assignments. Go for this option only if you are 100% sure about your input source to be safe.
Practice all of the three ways in your Post Model as below:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
protected $guarded = []; // Allow Mass Assignment for all field. !! Watch Out !!
// protected $guarded = ["id"]; // Guard id column and allow the rest
// protected $fillable = ["title", "slug", "excerpt", "body"];
}
Contributed to the Blog Project on GitHub.
26