DEV Community

Cover image for Laravel - Livewire security
Darius Dauskurdis
Darius Dauskurdis

Posted on

Laravel - Livewire security

In official Laravel Livewire page https://laravel-livewire.com is written "Tools like Vue and React are extremely powerful, but the complexity they add to a full-stack developer's workflow is insane." and I am totally agree. Sometimes we need static pages applications, sometimes with interactive components, but the problem is that we have no time to learn new framework for small or middle size projects. Livewire is framework too, but this framework has strong relations with Laravel, so full-stack developers can create interactive applications on frontend without leaving backend. Livewire can be your best friend when you need to create CRUD pages, eshop cart, review forms with ratings or other interactive objects, but if we are talking about interaction, it means, we need to have in mind that data will be visible on user's web browser. Let's say we have CRUD created with Livewire. On form submit in web browser's console we will see that we sending many variables with values. No problem if this data is just blog title or description, but what if we have companies or users with sensitive data, or field with company id which can be easily changed in web browser by changing value of inspected object. It means user can change company id and he will be able to get information about another company. Of course we need extra security on backend side, to check if this user belongs to this company or not, maybe we can implement Laravel role-based access control package - Laratrust. But what we can do in easy way is to encrypt our information. So let's say we have button in Laravel blade template, which deletes company user.

<button wire:click="deleteUser({{$user->id}})">Delete user</button>
Enter fullscreen mode Exit fullscreen mode

But in web browser you will see:

<button wire:click="deleteUser(12)">Delete user</button>
Enter fullscreen mode Exit fullscreen mode

And this 12 can be changed to another value. Luckily blade supports Laravel encryption service like "Crypt". So in blade file we can add:

<button wire:click="deleteUser('{{Crypt::encrypt($user->id)}}')">Delete user</button>
Enter fullscreen mode Exit fullscreen mode

So in web browser we will see something like this:

<button wire:click="deleteUser('tOJpdiI6InZQcEpmSW1NdkNjK3pyd1lWM2JyY3c9PSIsInZhbHVlIjoiM0pBQWpnABK6R3NIT1ZtdGlGT0Fjdz09IiwibWFjIjoiYjhkMDBjYzk5NzcxZjRhMjJjYjVmNzM2MTk5M2MwZjY1MWEzMWQ2ZTZjNzkzZDk3YjI0NTkxYmE4NmJhOTcwMSJ9')">Delete user</button>
Enter fullscreen mode Exit fullscreen mode

Don't forget to add single quotes for function parameter, because after encryption this parameter becomes string.
In our Livewire component class we can add "deleteUser" method.

public function deleteUser($id)
{
    try {
        $id = Crypt::decrypt($id);

        ...
        Remove user from company by decrypted id
        ...

    } catch (DecryptException $e) {
        ...
        Return error
        ...
    }
}
Enter fullscreen mode Exit fullscreen mode

Don't forget to add "DecryptException" contract and "Crypt" facade

use Illuminate\Contracts\Encryption\DecryptException;
use Illuminate\Support\Facades\Crypt;
Enter fullscreen mode Exit fullscreen mode

Another important thing is what kind of information we have in our component's class public variables. Maybe it is not the best solution to loop Model items, but it can be very helpful to filter information we don't want to show.

$this->company_users = [];
foreach ($company->users as $key => $company_user) {
    $temp_user = [
        'id' => Crypt::encrypt($company_user->id), 
        'name' => $company_user->name,
        'surname' => $company_user->surname
    ];
    $this->company_users[] = $temp_user;
}
Enter fullscreen mode Exit fullscreen mode

So it means we will add to $this->company_users variable only information we can show on web browser and user id will be encrypted.

Top comments (4)