Introduction to Javascript Prototype
- Almost everything in JavaScript is an object - including arrays, browser APIs and functions.
- The exceptions to this are: null, undefined, strings, numbers, booleans and symbols.
- JavaScript also does not use class declarations, but the “class” keyword is a helper function to make it easier for class-based programmers.
class Animal() {
constructor() {
this.cute = false;
this.delicious = true;
}
isFood() {
console.log("Checking if edible")
return this.delicious
}
}
============
moo = new Animal
moo.isFood() // true
typeof moo // 'object'
typeof Animal // 'function' and not 'class'
- In the past, classes in JavaScript were created using constructor functions ```js function Animal() { this.cute = false; this.delicious = true }
Animal.prototype.isFood = function() { console.log(“Checking if edible”) return this.delicious; }; ============ moo = new Animal moo.isFood() // true typeof moo // ‘object’ typeof Animal // ‘function’
moo = new Animal meow = new Animal
moo.color = “Black and White” meow.color =
What is prototype pollution?
Prototype pollution refers to a JavaScript vulnerability in which an attacker can inject properties in every object created by an application.
Prototype pollution vulnerabilities often appear in libraries that merge or extend objects. For a web application to be vulnerable to prototype pollution in an exploitable way, it must use a vulnerable merge/extend function and provide a path to code execution or authentication bypass using the injected properties.
Not always a security issue
Prototype pollution was not always considered a security issue. In fact, it was used as a feature to extend JavaScript in third-party libraries. Examples include:
- Adding a first() method to all array objects to return the first item within an array
- Adding a toISOString() method to all Date objects to return the date in an extended ISO format (2011-10-05T14:48:00.000Z)
- Native implementation would come out that is more efficient but replaced by the third party API.
Security Issue
- It is an issue if the application accepts user input and allows injection directly into the prototype of Object
- This generally occurs in extend, merge or clone type functions, which aim to merge objects to create new objects inheriting the properties of both objects. ```js const { isObject } = require(“util”);
// merge function accepts two objects ‘a’ and ‘b’ function merge(a,b) {
// each key of the second object is iterated for (var key in b){
// if the value of the respective keys are also objects, the function recursively iterates
if (isObject(a[key]) && isObject(b[key])) {
merge(a[key], b[key])
// otherwise the value of 'a' key is set to the value of 'b' key
} else {
a[key] = b[key];
}
}
// object ‘a’ is returned return a }
x = {“hello”: “world”} y = {“foo”: {“bar”: “foobar”}} merge(x,y) // { hello: ‘world’, foo: { bar: ‘foobar’ } }
x = {“hello”: “world”} y = {[“proto”]: {“bar”: “foobar”}} //[“proto”] ensures that it is enumerable merge(x,y) // { hello: ‘world’ } ```
