In Depth: Don't Trust Public Livewire Properties
[In Depth #39] Public Properties may look like PHP class properties, but they're really hidden form fields, just waiting for your input... 😈
Let's take a look at a rather fun (quite common) weakness associated with Laravel Livewire - manipulating public properties. In Livewire, public properties are synced between the server and browser, allowing both sides to access and manipulate them as needed. However, because they are defined as standard PHP public properties, it's incredibly easy for us as developers to think of them as such, even though they are no longer trusted or safe. Herein lies the weakness to be exploited.
Let's look at a really simple example:
#[Title('Title demo')]
class TitleDemo extends Component
{
public string $title = 'Hello, world!';
public function render(): View
{
return view('livewire.title-demo');
}
}Title Demo Livewire Component
Which looks like this in the browser:

If I change the title in the text box, the title on the page changes too. That's Livewire working its magic with the wire:model.live="title" property defined on the input field.
However, even if that input field is no longer present, we can still change the value on-demand, using the Livewire Javascript object...
Livewire.first().set('title', 'PWNED')
Now, we could leave it here, but that feels like a harmless exploit you have some fun with in your local browser. However, there are some significant implications that we really should explore to understand the full scope of this weakness - plus, we should have some fun in the process! 😈