avatarCyberPanda

Summary

The website content discusses mass assignment vulnerabilities in Laravel applications and provides prevention tips to secure against potential exploits.

Abstract

The article titled "Mass Assignment Vulnerabilities in Laravel Applications" highlights a common security issue where developers inadvertently allow unauthorized modification of database records due to improper use of Eloquent ORM's mass assignment feature. The vulnerability arises when sensitive fields, such as user roles, are included in the $fillable attribute, which can be manipulated by attackers to gain elevated privileges. The article uses a real-world example from a security code review conducted by CyberPanda, illustrating how an attacker could register as an administrator by submitting a crafted payload. To mitigate such risks, the article suggests validating and whitelisting only safe fields for mass assignment, using Laravel's built-in validation methods, and avoiding the forceFill method unless absolutely necessary. It emphasizes the importance of careful management of the $fillable attribute as applications grow and interact with multiple APIs or roles.

Opinions

  • The author advocates for the use of $request->validated() to ensure only validated fields are passed to the model, effectively preventing mass assignment attacks.
  • The article suggests that relying on $fillable for simple applications is acceptable, but as applications scale, developers should be more diligent in managing what data can be mass assigned.
  • The author emphasizes the importance of a whitelist approach using $fillable over a blacklist approach with $guarded to avoid accidental exposure of new columns.
  • The author warns against the use of $model->forceFill($data) due to its ability to bypass $guarded and $fillable checks, recommending caution and ensuring user data cannot be manipulated if this method is used.
  • The article promotes CyberPanda's services in security code reviews and pen-testing, implying that regular security assessments are beneficial for maintaining application integrity.
  • The author encourages further reading on Laravel security by referencing CyberPanda's Laravel Security Ebook, indicating a belief in the value of in-depth knowledge and continuous learning on the subject.

Mass Assignment Vulnerabilities in Laravel Applications

Photo by Karol Kasanicky on Unsplash

Eloquent like many other ORMs have a nice feature that allows assigning properties to an object without having to assign each value individually, this is a nice feature that saves a lot of time and lines of code but can lead to a vulnerability if used incorrectly.

For example here is a simplified example of an insecure code that we found during a security code review for one of our clients

The issue here is if a malicious attacker submits the payload below, he will be able to register an admin user with higher privileges and probably take over the admin panel of the application.

{ 
  "name" : "Hacker",
  "email" : "[email protected]",
  "role" : "administrator",
  "password" : "some_random_password", 
  "confirm_password" : "some_random_password"
}

Also, you might wonder here why role is in the $fillable attribute, if the "role" wasn't there, there would not be a security issue. The reason that it was added there is that there was another API that would allow changing role too, this is a common pattern that we see in Laravel applications that we review or pen-test, while $fillable is great if you have a simple application, it gets hard to manage when application growths and there are multiple APIs(or Roles) that are updating/creating a same type of model with different ACL roles.

Here are a few tips on how you can prevent mass assignment vulnerabilities in Laravel applications.

Prevention tips

Pass to model only fields that have been validated This is probably the most effective method of dealing with mass assignment attacks, instead of passing the full data from the request, you can pass only fields that have been validated. In the above code example that will be the name, email and password. To do so, Laravel provides you with a $request->validated() method, that returns you only fields that have been validated. So in the code above, replacing $request->all() with $request->validated() would fix the issue.

$user = new User(); 
$user->role = User::ROLE_USER; 
$user->fill($request->validated()); 
$user->save(); 

If you are not using Laravel’s request validation, you can also use $request->validate() or $validator->validated() which also returns only data that has been validated.

Use whitelisting instead of blacklisting We encourage using $fillable(which is whitelisting only columns that can be mass assigned) instead of $guarded(defines properties that can't be mass assigned) because you may easily forget to add a new column to a $guarded array, leaving it open for mass assignment by default.

Use $model->forceFill($data) method with caution forceFill ignores all the config that is set in $guarded and $fillable properties and saves passed data as it is into the model. If you have to use forceFill, make sure passed data can not be manipulated by the user.

Originally published at https://cyberpanda.la.

If you want to read more about Laravel Security, check out our Laravel Security Ebook.

Laravel
Application Security
Penetration Testing
Laravel Security
Mass Assignment
Recommended from ReadMedium