laravelmass-assignment

Laravel do I have to worry about mass assignment when setting field by field


I am a bit confused when it comes to laravels mass assignment.

I know that I can protect fields using:

protected $fillable = [
        'username', 'email', 'password'
    ];

and be protected here:

$flight = App\Flight::create(Input:all);

or

$flight->fill(['name' => 'Flight 22']);

But I only create or update Models like this:

public function createUser(NewUserRequest $request, User $newUser)
    {

$newUser->insertUser($request);

}

insertUser looks like this:

public function insertUser($request)
    {
        $newUser = $this;
        $newUser->user_type = (int) $request->input('user_type');
        $newUser->username = $request->input('username');
        $newUser->email = $request->input('email');
        if ($request->filled('password')) {
            $newUser->password = bcrypt($request->input('password'));
        }
        if ($request->filled('facebook_id')) {
            $newUser->facebook_id = $request->input('facebook_id');
        }
        $newUser->save();

        return $newUser;
    }

As you can see I always pick what fields I want to insert and what data should be inserted. So do I really need to set my $fillable when I dont use the create() or fill() methods?


Solution

  • The purpose of mass assignment protection is to protect developers who source model properties direct from user input, for example:

    Example::create($request->input());
    

    Without mass assignment protection a user who knows about the underlying application architecture could inject values into fields they're not expected to have access to, e.g if your User field has an is_admin value they could change their is_admin to 1 instead of 0.

    Mass assignment protection is only required when working with unsanitized user input and mass assignment protection is only enabled by default when mass assigning. You have 3 options for a secure application:

    1. Make use of mass assignment and whitelist each property in $fillable
    2. Assign values individually so there is no mass assignment protection, e.g: $user->name = 'John Doe'
    3. Disable mass assignment protection and do not mass assign from user input, e.g:

      protected $guarded = [];
      
      Example::create($request->only('name', 'age'));
      
      Example::create(['name' => $request->name, 'age' => $request->age]);
      

    You do not need need to disable mass assignment protection in your example because you are not mass assigning values, you're assigning a value to each property individually. You can determine if you are using mass assignment by asking yourself "Am I passing in an array of properties and their values?".

    You can learn more about mass assignment in the Eloquent documentation.