تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

Exposing Class Names0:31

Livewire can be. I did it just naturally, and then I went to try to hack it and found it's pretty easy. Yeah, so actual Livewire has lots of measures in place to prevent this kind of thing, just so you know. And we're going to implement one or two of those measures just to give you an idea of what Livewire actually does to sort of lock this down a little bit. But yeah, I want to show you, yeah, the most basic attack vector for this. In this snapshot here, we load the page. First things first, we have a class just put in HTML. If nothing more, a hacker now has more information about your application.

First things first, we have a class just put in HTML. If nothing more, a hacker now has more information about your application. They know that you're using Laravel. Well, they already kind of knew you're using Laravel. They could just look at your cookies or that you're using Livewire. But it's kind of an interesting thing. As a framework developer, I don't want to reveal anything about your application that you didn't intend to be revealed. Like a lot of people don't care that, you know, an actual class from their app is shown to the front end.

Like a lot of people don't care that, you know, an actual class from their app is shown to the front end. But there are people who would care because it does reveal something about your application. It reveals that you have an app folder and an Http folder and a Livewire folder. So they have information about the namespaces and things about your application. So in real Livewire, this is obscured. This does not show up in the front end at all. What would show up would be name and then to-dos. So it's just the name of the component. In fact, if you look inside your bootstrap folder on any actual Livewire app, bootstrap,

So it's just the name of the component. In fact, if you look inside your bootstrap folder on any actual Livewire app, bootstrap, cache, there's a Livewire components file. And it's a little lookup table where the keys are the names of the components and then the values are the actual classes. So this information that I consider somewhat sensitive or privileged information, I make sure I'm careful to store this on the server and then just use this key as a lookup. Okay, so that's one thing that actual Livewire does. But the other really, really important thing is right now, any of this data can be tampered with in JavaScript and you could do anything you want.

Demonstrating Snapshot Tampering2:21

But the other really, really important thing is right now, any of this data can be tampered with in JavaScript and you could do anything you want. We could change this class to a totally different PHP class, any class we wanted. And we could change this data to whatever we want. And our version of Livewire isn't going to stop us. So let's demonstrate that actually. Let's go to the console. We have this element here. Let's grab our snapshot. If you recall, it's __livewire.

Let's grab our snapshot. If you recall, it's Livewire. So here's our snapshot. So first thing, this class here. What if we change this class to a completely different class? Let's say app\Models\User because most Laravel apps by default have the User model right there. So if I hit enter, now, our system is going to try to actually new up the User class inside of Laravel, which is pretty dangerous. And we can do even more danger.

of Laravel, which is pretty dangerous. And we can do even more danger. Let me show you the database. And so this is a little database I have for this app. There's a single User whose name is Caleb Porzio with my email address and the password and whatnot. And we're going to try to hack this User to get access to it. So if we change class to App\Models\User, that's good. And then we can also go further in this data here. Let's set it to entirely new data.

And then we can also go further in this data here. Let's set it to entirely new data. Because what's going to happen if you recall, let's look at the actual code that does this. When we call from snapshot, so that's what happens when the snapshot comes back to the server, we whatever, we just knew up the class. So now we know that the User, this will be a blank User model, because we'll say new app\Models\User. And then depending on the data we send along, we can very easily set any properties we want. And then even more than that, we can call any method we want. So we could set the data to anything we want, and then call save on that User model.

And then even more than that, we can call any method we want. So we could set the data to anything we want, and then call save on that User model. And it will hijack our model. So let's do that. So livewire.data, let's say we want the name to be hacked, Caleb, Kalib. And then we want, we want the ID to be the number 1. And then the email to be fake_email@gmail.com. Okay, and then the last bit we need here is exists is true. And this is if you just know Eloquent, you know that you need this to tell Eloquent that this model exists so that when we call save, it just overwrites the existing model.

And this is if you just know Eloquent, you know that you need this to tell Eloquent that this model exists so that when we call save, it just overwrites the existing model. Alright, so we set that data. The last little bit to hack this is let's change wire:click to save. Alright, so now if I add toDo watch this add toDo, okay, well, it's broken. But what is the break? The break says called undefined method render. Alright, so we can see that we're already in the app, we've done what we needed to do. It's trying to call render to render this component, but it doesn't have it. But the damage is already done.

It's trying to call render to render this component, but it doesn't have it. But the damage is already done. Take a look at table. Plus, if I refresh, there it is hacked Caleb with a fake email, you could replace it with your own email address, you could then go to forgot password. And you could change it to whatever password you want and hijack somebody's account. You could change the password directly. There's all sorts of damage that you could do. This is just scratching the surface. So hopefully that scared you enough to be eagerly awaiting how we're going to secure.

Introducing Checksums5:32

This is just scratching the surface. So hopefully that scared you enough to be eagerly awaiting how we're going to secure this. So the first thing like I said that Livewire has that lookup table, you wouldn't be able to just set an arbitrary php class in real Livewire, even if Livewire didn't have other security measures, it would only allow you to tamper with an actual Livewire component. So that may, you know, that's one effort to just mitigate this entirely. But the more robust thing, this is kind of the crux of security in Livewire is all snapshots have a checksum attached to them. And what is a checksum?

snapshots have a checksum attached to them. And what is a checksum? You may have seen a checksum around computers, because it's a somewhat, it's a commonly used concept. If you're passing along a bunch of data, and you need to make sure that it's not tampered with, then you might boil it down to a hash, and then send that data back with that hash, and then some system can verify that that data would create that same hash. So if that didn't make sense, it's easiest to kind of show it to you more in action. So let me open php artisan tinker. And let's look at a few, let's look at hashing in PHP to begin with.

So let me open php artisan tinker. And let's look at a few, let's look at hashing in PHP to begin with. So there's a few different hash methods. And first off, what is a hash, a hash is basically taking some string, like, hey, there you and turning it in. So let's use md5. It's a really basic hashing algorithm. We run md5. And then we get this string based on this string. So this string could be a zillion characters long.

And it's basically kind of useless. Because anybody can easily like there's just tools, free tools online, you could just basically take this hash and say, hey, what created this hash, and it'll probably find the word, hey, in no time, because of md5, you know, lookup tables, whatever, we don't have to get into that. But that's what we're going to use, because it represents this hash concept in a very plain and simple way. Actual Livewire does much more secure things than just an md5 hash. But we're just going to use md5 to give you the basic concept. Okay, so let's do some securing.

Generating Snapshot Checksum8:21

But we're just going to use md5 to give you the basic concept. Okay, so let's do some securing. Let's start with snapshot. So when we create the snapshot, here's our snapshot, we need to add a new key called checksum. And that's going to be that md5 hash of the entire snapshot. But we can't just pass in snapshot because it's a part of the snapshot. So what we need to do is let's create, basically, we can do this, we could say snapshot.checksum. So let's create a new key called checksum. And then set it to we'll put this in a separate method, we'll say generateChecksum.

So let's create a new key called checksum. And then set it to we'll put this in a separate method, we'll say generateChecksum. And then we'll pass in the snapshot. And then this checksum key will get set to a new checksum that we generate. So let's do that. Let's create a new function called generateChecksum, where we turn this snapshot into a hash, and that'll get set as the checksum. So md5, and we can't just pass in data, we have to pass in a string. But remember, you can easily turn any, like, let's, okay, if we dd this snapshot, show you in the browser, okay, there's our data there, class data meta, okay.

But remember, you can easily turn any, like, let's, okay, if we dd this snapshot, show you in the browser, okay, there's our data there, class data meta, okay. Now if I dd json_encode, we can turn that data into a string by json_encode. So we can take this JSON encoded bit and put that inside md5. And now let's actually dd this out. Let's say dd, okay. And then this is our hash of that data. And when that data changes, that hash will change. Okay, we'll load this on the front end. Let's take a look at our HTML and make sure that we have a checksum.

Okay, we'll load this on the front end. Let's take a look at our HTML and make sure that we have a checksum. And we do. So now when we send this back to the server, when we do something, let's take a look at what just got sent to the server. Inside our snapshot, we now have a checksum that we can use, we could basically take all of this data, md5 hash, the JSON encoded version of this, and check that these two are equal. And then we know that we're dealing with a good snapshot. So let's go to this from snapshot, the second part of Livewire, when we get the data back

Verifying Checksum Server-Side10:22

And then we know that we're dealing with a good snapshot. So let's go to this from snapshot, the second part of Livewire, when we get the data back to the server. And first thing right away, let's do the verify, verifyChecksum. And then we'll pass in the snapshot, okay. And then we'll create a method called verifyChecksum. And then inside of verifyChecksum, we need to do two things, we need to get the checksum out of the snapshot. So let's say checksum equals snapshot->checksum. And remember, it was generated without the checksum because you know, you can't have

So let's say checksum equals snapshotChecksum. And remember, it was generated without the checksum because you know, you can't have the checksum inside the checksum. So we need to unset snapshotChecksum so that we're dealing with the snapshot object without the checksum key. Okay. Now we can generate a new checksum and see that it matches exactly and throw an error if it doesn't. So let's do this. Let's say if checksum is not equal to, and then we'll generate a new one, generateChecksum

So let's do this. Let's say if checksum is not equal to, and then we'll generate a new one, generate checksum and pass in the snapshot, and we know that it's something's been tampered with inside the snapshot. So we can throw a new Exception. And that is going to say, hey, stop hacking me. Okay. Refresh. And let's see if this worked. Okay.

Now let's try to do that hack again and see that this checksum system has prevented it. All right. So we changed data to something arbitrary and hit add to do. We now have a 500 error and it says, hey, stop hacking me. Okay. So that is like the most important thing to understand when you're understanding Livewire security features. And it is also a really helpful bit of knowledge because in Livewire, sometimes that's those snapshots that data gets tampered with by the browser itself in no malicious way. But if you think about it, let's say if an array is in one order in php, and then that

Checksum Edge Cases12:23

snapshots that data gets tampered with by the browser itself in no malicious way. But if you think about it, let's say if an array is in one order in php, and then that array goes into JavaScript and JavaScript reorders the array because it's a different language. And then it tries to go back to the server, php will be like, hey, this snapshot doesn't match the checksum and it'll throw a fit. And so you've probably encountered that at some point because it is an actual hurdle when building Livewire. There's a lot we have to do to take data and try our best to guess how JavaScript is going to handle that data so that we don't get those snapshot errors.

about it. Another one is when you load a page, all the middleware that got used to load the page and load this component on subsequent requests, those same middlewares will get applied to those subsequent requests. So if you have authorization or anything like that, it'll get persisted to multiple Livewire requests so that that's basically Livewire's answer to security to try to keep things as secure as possible. Of course, if you think of anything that Livewire isn't doing, or any attack vectors, report them immediately. But so far, you know, we've plugged up the holes and that's that.

ChecksumsHashing

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟