Top Laravel Security Practices and Avoiding CSRF and SQL Vulnerabilities
When it comes to the world of PHP, Laravel has long established itself as a popular web framework for both advanced and newbie developers. Owing to its wide set of features as well as the ability to handle a lot of MVC-based apps, Laravel is the de facto framework of choice when it comes to building rich and interactive PHP web applications.
Laravel comes with a good set of security measures and methods of its own. In fact, it is one of the most secure web frameworks out there. This is also amplified by the fact that the Laravel team is rather quick to fix and patch any security vulnerabilities as and when these are discovered.
With that said, nothing can ever be taken for guarantee and at the end of the day, the security of your application and website rests with you.
So, how can you secure or harden your Laravel web app? In this article, we will be taking a look at some of the key security measures that you can implement on your project.
Bear in mind, this article assumes that you already know your way around Laravel and are familiar with its mode of operation.
Avoiding Cross-Site Request Forgery (CSRF)
If you have used Laravel for a while, you probably already know that Laravel uses CSRF tokens to prevent unauthorized third party applications from passing fake access calls or requests. In this manner, Laravel essentially ensures that known security vulnerabilities too are hard to exploit.
Basically, for each AJAX call, Laravel generates and integrates an access token with the request. Now, whenever we invoke the said request, Laravel also compares the said token with the one saved in the current sessions. If the request tokens match, all is fine. If not, the request is invalid and ignored.
For old school developers that manually create forms, it is often necessary to pass the correct CSRF tokens in order to ensure that the access requests do not throw a security exception. For the most part, here is how to do it:
default<form name="myform"> {!! csrf_field() !!} <!-- Other inputs may come here--> </form>
Preventing SQL Injections
SQL injections continue to remain one of the biggest and most common ways to compromise a PHP website or application. Essentially, an SQL injection is a way in which a malicious hacker can modify or compromise the actual intent of database queries, thereby affecting the entire web app adversely.
Here is a sample database query:
defaultSELECT * FROM users WHERE email = 'someone@domain.com'
All we are doing is selecting all such entries from the users where email matches the one that we specified.
Now, what if the above query were modified as follows:
defaultSELECT * FROM users WHERE email = 'someone@domain.com' or 1=1
The above query will always fetch all the records, as 1=1 is a simple logical expressions that is, obviously, true. Naturally, this can spell disaster for our database and content.
Laravel has a simple method of tackling this. It makes use of PDO parameter binding, where the input is placed in quotes. As such, our query will look like this:
defaultSELECT * FROM users WHERE email = 'someone@domain.com or 1=1'
Now, no records can possibly match the above query and as such, the query will not return any records.
For the most part, the PDO binding, as shown above, should suffice for most development scenario. However, many developers often make use of raw queries for a various range of purposes -- be it sheer habit or absolute necessity.
In such cases, if you are required to use raw database queries, you can still take certain precautions with your queries to prevent SQL injections.
Here is an example of a raw database query that is highly likely of being vulnerable to an SQL injection attack:
defaultRoute::get('a-bad-query-example', function() { $name = "'Joshua' OR 1=1"; return DB::select( DB::raw("SELECT * FROM users WHERE name = $name")); });
The above raw query, as effective as it might be, is a poor security practice. But we can structure it this way:
defaultRoute::get('a-good-query-example', function() { $name = "'Joshua' OR 1=1"; return DB::select( DB::raw("SELECT * FROM users WHERE name = ?", [$name])); });
In the above query, we are actually passing a question mark with the query variable. Laravel can automatically replace the question mark with the query variable, thereby eliminating the need to rely on escape variables. This means the raw database query, as we passed in the second case, is not highly prone to SQL attacks.
Using Laravel Security Packages
Laravel comes with quite a good deal of out of the box security measures. As such, for most of the basic use cases, it does not really suffer from security issues.
However, for advanced or large-scale setups, it becomes rather vital to rely on certain key security packages. Here are some recommendations:
- Laravel Security
- Laravel Security is a fairly popular package, especially when it comes to tackling XSS vulnerabilities.
- Laravel ACL
- Laravel ACL can offer role-specific permissions for the authentication mechanism. If your application makes use of CRUD controller methods, Laravel ACL is a wise choice that ought to be used.
- Laravel Security Component
- LSC serves one basic purpose - it integrates the Symfony security core within Laravel. Thereafter, it enables developers to use role-specific security validation, check access privileges, and keep track of loopholes surrounding roles and objects.
Among Other Things...
It goes without saying that you should only share sensitive information over HTTPS for added security. Furthermore, to avoid XSS attacks, it is often a wise strategy to use the double brace syntax in blade templates, for instance:
default({{ $variable }})
The Laravel curly braces ensure that no sensitive data is revealed to the user in the form of raw HTML. Of course, at times it might be necessary to yield HTML variables from the database to the user. For that purpose, we can make use of the HTML purifier in Laravel.
That pretty much sums up the Laravel security practices that one needs to bear in mind,. It is a noteworthy point that Laravel, if configured properly and updated regularly, is a robust framework that does not suffer from a wide range of security issues. As a Laravel developer, all one needs to do is to ensure that the database scripting attacks are properly circumvented.
If you are a Laravel developer, what security measures do you use and how? Share your views in the comments below!