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...
Premium Members Only
This advanced tutorial is available exclusively to Laravel Daily Premium members.
Already a member? Login here
Premium membership includes:
Nice article with a lot of good tips that are easy to overlook!
One tip I'd suggest is that when handling files uploaded through the request, don't use
getClientOriginalName()orgetClientOriginalExtension()when storing on the server, especially in a publicly-accessible directory.The safer alternative is to simply use the
hashName()(generates a random filename) andextension()(based on MIME-type, in line with Laravel's validation) methods.Here's these methods in the Laravel docs. Stephen Rees-Carter also has a great write-up about this too.