gustavgans
gustavgans

Reputation: 5191

How to prevent SQL injection in Laravel?

In my controller I have this code:

public function create($brand_id)
{
    Brand::findOrFail($brand_id);
}

and this:

public function search() 
{
    $q = Input::get('q');
    $brands = Brand::where('title', 'LIKE', '%'.$q.'%')->take(80)->get();

Is this code safe? By "safe" I mean SQL injection safe. Or should I do some variable clean up here? And what is the best way for cleaning up user input? Thanks a lot for helping me :)

Upvotes: 27

Views: 43374

Answers (3)

Joel Harkes
Joel Harkes

Reputation: 11661

Yes but note not all parameters are safe in the where statement:

public function search() 
{
  $col = Input::get('col');
  $brands = Brand::where($col, 'LIKE', '%sql injection in column name%')->take(80)->get();

In this case sql injection is possible!

The first parameter: the column name is not validated or checked and sql injection is possible here, make sure you protect this properly yourself!

Order by

Order by is also not safe if you use user input:

   $query->orderBy($request->input('unsafeInput'))

Safe dynamic queries

If you do want dynamic query filters, I would suggest keeping a list on the Eloquent model or on the Controller which fields you want to allow filtering (keep in mind privacy concerns when you ca filter on a field that is not in the final result/response).

array $filterable = [ 'columns', 'user', 'can', 'filter', 'on'];
check(in_array($unsafeInput, $filterable));

This way you can keep some control over the filtering. We did this when we started our software. It's great to quickly get going but later on it can get in the way as it is harder to figure out how people call your API, than having query explicit filters.

Upvotes: 3

Master Bee
Master Bee

Reputation: 1099

yes Eloquent uses parameter binding behind the scene, which safely escapes any input used in where().

Upvotes: 36

Anurag Khandelwal
Anurag Khandelwal

Reputation: 281

Document says that Eloquent handles this behind the scene but you can also use like DB::escape($q) to be in safer side

Upvotes: 5

Related Questions