Do you think you write SECURE code in Laravel? Let's see if you follow these 9 pieces of advice about security in Laravel.
1. Don't use $request->all()
Don't use $request->all()
when creating or updating a record.
Controller:
public function store(StoreUserRequest $request) { User::create($request->all()); // A BIG NO-NO!!! return redirect()->route('dashboard');}
When using the all()
method, it will take all data from the request, even if you have validated it before. So, some people may try to guess your DB fields and send something like is_admin => 1
as a part of the request.
A better approach would be to use $request->only()
and provide an array of values.
public function store(StoreUserRequest $request) { User::create($request->only('name', 'email', 'password')); return redirect()->route('dashboard');}
Or, if you are using Form Requests for validation, even better way is to use $request->validated()
which will take ONLY the keys that were inside of the rules()
method of the Form Request.
public function store(StoreUserRequest $request) { User::create($request->validated()); return redirect()->route('dashboard');}
We have a more in-depth tutorial about $request->all()
here.
2. Raw SQL Queries Parameter Binding
When making a query using the raw syntax, be careful how you inject values. For example, you have a products list and would query by a min price:
$minPrice = $request->input('min_price')$products = Product::whereRaw("price > $minPrice")->get();
If user wouldn't alter the query param everything would work. But, in this case, if user would pass $minPrice = "0 OR '1'='1'"
, they would get ALL the products.
A proper way would be to use parameter binding.
$minPrice = $request->input('min_price');$products = Product::whereRaw("price > ?", [$minPrice])->get();
This way when the same query would be tried to execute an error would appear instead: Illegal string offset "0 OR '1'='1'"
.
Another example of such non-sanitized SQL parameter is a classical xkcd comic:
And, of course, add the parameter validation beforehand.
3. Don't Leave APP_DEBUG=true
In Production
Leaving APP_DEBUG
set as true
can end with serious consequences. If you do that, in case of error the user receives the full information instead of a general message like "Server Error" or "Service Unavailable".
So, they could see sensitive information through detailed error messages, including stack traces, environment variables, database credentials, etc. This information could give attacker a lot of information for further exploitation.
In other words, APP_DEBUG=true
will allow users to see the same error information as you see locally.
4. Don't Forget To Set APP_ENV=production
In Production
When APP_ENV
is set to production
, Laravel...