Hello. Welcome to secure JavaScript programming with Vladimir de Turckheim. This video is here to explain you what is prototype pollution and how to protect against it. Prototype pollution is one of the fastest growing vulnerability in the JavaScript eco system and in the programming world in general. Between 2018 and 2020, there had been 96 CVE entries for prototype pollution. It's a very nasty bug. We will see in the next course how it can be used to obtain, for instance, remote code execution. But in this video this is current course, we will mostly focus on how it works. If we check the least of CVEs here, we can see that there was one on lodash for version before 4.17.11. Lodash is actually an extremely popular JavaScript library for Node.js and the browser. Literally thousands of websites use lodash and thousands of back-end applications use lodash. Only for npm-version, it's downloaded 43 million times a week. That's huge. We can see that the versions before the patch, I remind you that the patch was for 4.17.11. Those versions before the patch are still insanely popular. Let's just take 4.17.10. It's downloaded 500,000 time per week. Same thing for, 4.17.4. We've got more than 1 million and much more than 1 million or 10 millions, download of venerable versions of lodash every week. Despite these versions being published years ago, people still download them. What is this vulnerability in lodash? Well, we will see it in lodash and in another package that is also a UT library named Hook. Let me npm install. As you can see, I have taken lodash in a vulnerable version. Same thing for Hook. Now we've got our dependencies that have been downloaded. On lodash dash, we will for now focus on these three lines of code. Here we've got console.log, a.hasOwnProperty. Hasownproperty is a standard method in JavaScript to check if an object has own property with a given name. Then we will call lodash.merge, the empty object or attack payload, but we will see that later. That's it. Now we will run exactly the same line. We will do the log of a.hasOwnProperty. Let's run this really quick now. We can see that before we ran lodash.merge, we had a function as a.hasOwnProperty. After its became a boolean. The function hasOwnProperty has been replaced by the boolean true. What happened? At the first line of this code, we require lodash and we have it in the _variable. That's the convention with lodash. Then we have a malicious payload as a string containing a JSON. The value is constrictor, prototype, hasOwnProperty, true. We create our object a and we log what we want to log before calling lodash. Then recall lodash.merge on an empty object. It can be any JavaScript objects, actually, for this attack to work. As a second parameter, we pass JSON.parse, the malicious module. What happened? The bug in lodash overwrote the value of hasOwnProperty of the global prototype of all objects in the JavaScript heap. I know that's a bit complex to get, and the rest of this video is about showing you another example of that, explaining in detail what is prototype pollution and how is it related to prototype inheritance. We will check and those who did at library. Then at the end of the video, I will show you multiple ways to protect against this attacks. Here we've got another library. We do the same. We created a object, which shows the value for hasOwnProperty, we do something else which is exactly the same, hook.merge empty object parsing another payload and then we show that the property has been replaced by no. If I wanted to show you exactly the same thing as the lodash example, I probably should put true in my malicious payload. In that case, we didn't go through overriding the value of constructor.prototype, we went through overriding the value inside proto Because those two libraries had the same vulnerability but under different kinds so the payload need to be built for the library. Before we go under the hood into the low dash bar, into the hook function, I need to do some refreshers on prototype inheritance. Let's say that I've got a class A that has a constructor. I don't know why WebStorm wants the default to be like that. Let's say this.a equals 1. Then on this class A, we will create a method, sayHello. In this method, we will just write console. Sorry, I've got some happy linters things console that log. Hello. Now we will create another class, class B that inherits from A, meaning that all objects that are created through the class B will have the prototype of the class B. But this prototype, we have as a prototype the class A. We will see that in details. Extends A common constrictor, this.B equals B. What did I do wrong. A previous, does it take point constructor? No. What happened? Yes, I forget the supercole. Then we will have a, sayHi method, console log Hi. Then we will create one last class, which will be C. C extends B. You know the drill, constructor this. C equals 3. That should be 2, let's try, stop being a terrible developer myself. Now, we will create a new instance C, then we console that log, what's inside C, and we do c. sayHi: c. sayHello. If we run this code, without any surprise, we'll have an object C, which has the value A:1 coming from the class A, B:2 coming from the class B, and C:3 coming from the class C. It also has a method named sayHi, and sayHello. Let's see exactly where in the JavaScript object these are present. Let's explore the C object. We see that the three properties A,B,C are directly on the object. However the sayHi, and sayHello method are not on the object itself. It's maybe on the prototype. Well, we check that, it's not directly on the prototype. It is on the prototype of the prototype. Let's understand. This value for proto, is actually the prototype of the C class. The C class, does not have any method. However, the prototype of the prototype of the C class is the prototype of the B class. The prototype of the prototype of the prototype of the C class, or in other words, a prototype of the prototype of the B class, is the A class prototypes. When we could see.sayHi, the algorithm under the hood we'll do, is there method named, say Hi directly on the C object? Is there a prototype, a property named sayHi? It would look like has own property, sayHi, it returns false. Now it will check C. proto. Does it has a property named sayHi? Still not. It will go one step up, and check under prototype of the prototype and now it's available. That's why it returns true now. But if I write sayHello, it's still not there. But I can find it under prototype of the prototype of the prototype. An interesting thing is that if you go really up into the prototype chain, you actually end up with a common prototype for the class object. All objects in the JavaScript heap integrate by default from this prototype. When you do a prototype pollution, you actually pollutes with an arbitrary value, something in the prototype chain. Either it will be on a class, either it will be directly on the global prototype. Let's see how it works under the hood because prototypes are just objects. Remember the hook one. I actually extracted the merge function from hook. It was easier to do than the merge function from low dash. We've got a method, isObject, that basically checks if something is an object. Basically, it has a constructor and this constructor is object, and we have the merge function. What it does is that it loops on the properties of the source object. We want to merge a source into a destination. We loop on the prototype of the properties of the source object, and for each of them if there is an object, we actually recursively go up into the function. Otherwise, we assign the property from source and the destination. That's pretty much where it happens. Because if you put underscore, underscore proto, well, it will just take the value of proto here and say, it has a value of proto and a source. The decision both have proto, which is an object. So I need to match, the content of the proto from the source to the destination. Let's see that in detail. Let's just first of all check this. Here, you can see that I have another payload that will add an environment value as an object on all elements. Here, I look new objects, that nth. Keep that in mind, that might be useful for the next video. Recursively, this function will actually add properties to the prototype. Probably something better to do, sorry. Let's do it this way. If we check the value of x here, we can see that this is an object. It has node of property, but under the prototype on proto and also a prototype of all new objects now, there is an nth property that has the value we maliciously added. That's how prototype inheritance can lead to prototype pollution. One legitimate question you may have is that, why is it always coming from a JSON.parse? Well, there's a reason. We will check it here. If I check the value of x and I will do something like that, that's a secret why those examples are always using JSON.parse. Here, I have x and I foster a value of proto. Well, you can see that it has just been ignored. That's it. It has been ignored when you define an object with a value proto like that. However, when you do that with JSON.parse, because of the internal of JSON.parse, it has created two properties named proto and the object. That's a very age case of JavaScript that was exploited here. Okay, so now how do we protect ourselves against it? Well, because it's due to prototype stuff, one way we could start replacing a would be to do const a equals object.create, null. This method actually creates an object which has null prototype because Object.create, creates an object from its prototype passed as an argument. If we have the prototype null, we are not really able to prototype pollution because we don't have a prototype. However, we won't from these methods but that's it. Another way to get to the same result without rewriting the object would be right after creating the object, use Object.setPrototypeOf a null. That gives the same result. We will set a null prototype right. My third solution, but this one might break some other stuff in your code is to freeze the prototype. We can do a dot proto. In that case, the value of the prototype is frozen and rewriting over it is either ignored, either throw an exception, depending if you are in strict mode. Last but not least, we could totally not use a and replace a by a new map. In that case, of course, we are still vulnerable to prototype pollution and a, but we wouldn't use method from the global prototype chain because we would use a dot has which are method of the map class not on the global prototype. We would not be vulnerable to actually using those methods for further story in the Node.js internal because I'm a Node.js contributor, we've got saved methods that have been frozen under prototype for the internals of node. Sorry, this was a very long video, but thanks so much for staying until the end. Prototype pollution is one of the most dangerous vulnerabilities in the JavaScript world right now, and please come and watch the next video when I will show you a live exploitation of a vulnerability, to get remote code execution on a Node.js application vulnerable to this.