Published: 10 Aug 2022
Reading Time:
Views: 377 views
Article Contents
one of the common mistakes between laravel developers including me, that they are like using request()->all();
Model::create($request->all()); // create a new record with all comming data
that is because it’s much shorter than defining each column you need to store in the database, but it might make a security issue in your application.
For example: if you have a priority fillable field that is only available for the administrators, so the attacker can guess the name of this field and pass it to the request through a hidden field inside the form, even if he doesn’t have any permission to do it.
so if you like to use $request->all(); you should be very careful about these priority fields.
there are several ways to protect yourself from this kind of attack.
add a new property protected $guarded to your eloquent model to refuse the priority fields to be filled and only accept the other fields in the fillable property.
for example:
class User extends Authenticatable
{
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable =
[
'name',
'email',
'password',
];
/**
* The attributes that aren't mass assinable
*
* @var array
*/
protected $guarded = ['is_admin'];
}
but wait a minute, there’s a little problem with this.
imagine you have another form in the admin panel that must give admins the ability to update guarded fields.
well, there are two ways to solve this.
public function store(Request $request)
{
$user = new User();
$user->is_admin = $request->is_admin;
$user->save();
}
public function store(Request $request)
{
User::forceCreate($request->all()); // the request containt the un assignable attributes, ex: is_admin
}
you can use the same ways while updating
you can use only() method that tells the eloquent to accept some attributes and avoid the rest of them.
public function store(Request $request)
{
User::create($request->only(['name', 'email', 'password']));
}
but what if you have tens of attributes, it will be so hard to define each one, and it doesn’t make sense.
in this case, you can use the opposite of only() method calls except().
the except() method accepts an array with the attributes you want to avoid, and it will accept the rest of the request attributes.
public function store(Request $request)
{
User::create($request->except(['is_admin']));
}
you can use form request to validate your request and only insert the validated attributes using validated() method.
class UsersRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return
[
'title' => 'required',
'email' => 'required',
'password' => 'required',
];
}
}
class UsersController extends Controller
{
/**
* Store a new user record
*
* @param UsersRequest $request
*/
public function store(UsersRequest $request)
{
$user = User::create($request->validated());
}
}
this will create a new user with the only fields you validated and avoid any other passed attributes.
And that’s it! Now you know how to protect your priority fields with some solutions, I always accept any advice, so if you find anything important or you have any additions to the same topic, please let me know!
Click one of our contacts below to chat on WhatsApp