Laravel Security Features

20 Jun, 2019 | 6 minutes read

Laravel is a free, open-source PHP web framework, created by Taylor Otwell. Everybody in the dev community has heard about Laravel and that is why I am going to skip a broader introduction. Instead I am going to focus on what we will cover in this article. Out of the box Laravel comes with many features making the application you are developing secure, which makes Laravel the go to PHP framework when it comes to critical applications. However, no framework can claim that is 100% secure and that is why in this article I ainterwm going to cover its features, vulnerabilities and how to get past them.

Laravel Authentication System

Laravel already has a robust user authentication process in place with the associated boilerplate code available in the scaffolding. Laravel uses providers and guards to facilitate the authentication process. The purpose of guards is to authenticate users for each request they make, while providers facilitate the retrieval of the users from the database. As a developer, all you have to do is set up the database, the controllers and the models. During the process, the authentication features are built into the app.

Cross-site Request Forgery (CSRF)

A Cross-Site Request Forgery (CSRF) is an attack that forces an end user to execute unwanted actions on a web application in which they’re currently authenticated. CSRF attacks specifically target state-changing requests, not theft of data, since the attacker has no way to see the response to the forged request. With a little help of social engineering (such as sending a link via email or chat), an attacker may trick the users of a web application into executing actions of the attacker’s choosing. If the victim is a normal user, a successful CSRF attack can force the user to perform state changing requests like transferring funds, changing their email address, and so forth. If the victim is an administrative account, CSRF can compromise the entire web application.

To help protect the data privacy against the Cross Site Request Forgery(CSRF) attacks, Laravel has introduced a user verification token named Laravel CSRF token, with a sole purpose to verify and validate the users sessions. It ensures that the request and approval for any particular resource/program is only given to the authenticated users who have verified tokens. If the Laravel CSRF token mismatches with the one stored in Laravel’s session, then it quickly denies access to the resource requested by that particular token.

Picture 1: Usage of @csrf in Blade directory
(Picture 1 – Usage of @csrf in Blade directory)

Laravel generates a particular CSRF token for each user session, which means real users can only access the required information by validating with the CSRF token. Every token is first checked and validated from the Laravel’s session, before giving access to any program or resource. If that Laravel CSRF token is not found in the stored session, then the access to the resource is denied.

XSS (Cross-site scripting)

Cross-site scripting (XSS) is a type of computer security vulnerability typically found in web applications. XSS enables attackers to inject client-side scripts into web pages viewed by other users. A cross-site scripting vulnerability may be used by attackers to bypass access controls such as the same-origin policy.
So for an example if the malicious intent user inputs this script into a field that is in a section which renders every time we go to the page:

Picture 2: Malicious script
(Picture 2 – Malicious script)

The result of this script when the page is accessed is the following:

Picture 3: Result of the malicious script
(Picture 3 – Result of the malicious script)

So every time the page is accessed this annoying script will pop up in a form of an alert window. This is the aforementioned attack called cross-site scripting(XSS).

Fortunately, when a variable is rendered within the {{ }} escape tags, Laravel will render in its place a string as the following one:

Picture 4: Result string after using {{ }} escape tags
(Picture 4 – Result string after using {{ }} escape tags)

Laravel’s {{ }} statements are automatically sent through PHP’s htmlspecialchars function to prevent XSS attacks.

Using this method keeps us safe from XSS attacks.

SQL Injection

SQL injection is a web security vulnerability that allows an attacker to interfere with the queries that an application makes to its database. It generally allows an attacker to view data that they are not normally able to retrieve. This might include data belonging to other users, or any other data that the application itself is able to access. In many cases, an attacker can modify or delete this data, causing persistent changes to the application’s content or behavior. In some situations, an attacker can escalate an SQL injection attack to compromise the underlying server or other back-end infrastructure, or perform a denial-of-service attack.

That is why Laravel’s Eloquent ORM uses PDO parameter binding to avoid SQL injection. Parameter binding ensures that malicious users can’t pass in query data which could modify the query’s intent. Consider for instance a form field used to supply an email address which might be used for searching a user table. But instead of supplying an email address the user searches for ‘igor@test.com’ or 1=1. Left unsecured, the resulting query might look like this:

Picture 5: Unsecured query
(Picture 5 – Unsecured query)

The 1=1 syntax, it is a simple logic expression that always evaluates to true, meaning when coupled with or, all records from the users table will be returned.

Consider a particularly malicious user who instead passing ‘igor@test.com’; drop table users; into the search field, meaning an improperly secured query would look like this:

Picture 6: Malicious query
(Picture 6 – Malicious query)

If the MySQL account responsible for executing the application queries happened to have the DROP privilege, the users table and all of the data found inside it, would be destroyed.

However, when PDO parameter binding is used, the supplied input will be quoted, meaning the former resulting query will look like this:

Picture 7: Safe query
(Picture 7 – Safe query)

Because no email address matches igor@test.com or 1=1, the query will safely return no results, thus keeping us safe from an attempted SQL injection attack.

Laravel ACL (Access Control List)

Laravel ACL provides role based secured permissions to the Laravel authentication process. ACL helps protecting routes and CRUD controller methods in the applications. ACL lets you limit user permissions – it is that simple.

In the following section I am going to demonstrate a short and easy way to create an ACL without creating extra tables or relationships.

First of all when creating the users table a user_type column should be added to the migration like this:

Picture 8: Adding user_type column to the users table
(Picture 8 – Adding user_type column to the users table)

After adjusting the migration of course we should migrate it with:
php artisan migrate.

Next we should create a policy for users in the AuthServiceProvider.php file and add the following code in the boot method:

Picture 9: Registering user type policy
(Picture 9 – Registering user type policy)

Of course we should import GateContract:

Picture 10: GateContract import
(Picture 10 – GateContract import)

And the custom ACL is done. It is that simple. Next I am going to show you a couple of usage examples.
The first example will be using Laravel’s Blade templating engine where it is fairly easy to use the created ACL. The usage is connected with the @can and @cannot directives:

Picture 11: Different roles can see different pages
(Picture 11 – Different roles can see different pages)

The second and final example will be backend related. The following example shows how the ACL can be used in a controller to add a permission for a specific page to a specific user:

Picture 12: Dashboard permission only for the admin role
(Picture 12 – Dashboard permission only for the admin role)

This concludes the demonstration for the short and easy creation and usage of the custom ACL. I believe that with very small adjustments, you can definitely use it in your respected project.
And if you need something professional and customizable I recommend the following two ACL packages:

Conclusion

But in the end there are always more things you can do to make your application secure. All in all Laravel ensures a much safer application with its built-in mechanisms and easy-to-use solutions for security. Next in the process of security would be the server side security, but that is a topic of its own. These features and the familiar model, view, controller (MVC) architectural pattern make Laravel one of the most popular PHP frameworks in the dev community.