原型链污染是什么

__proto__

一个Foo类实例化出来的foo对象,可以通过foo.__proto__属性来访问Foo类的原型,也就是说:

foo.__proto__= Foo.prototype
对象           构造函数

所以,总结一下:

  1. prototype是一个类的属性,所有类对象在实例化的时候将会拥有prototype中的属性和方法

  2. 一个对象的__proto__属性,指向这个对象所在的类的prototype属性

  3. 每个构造函数(constructor)都有一个原型对象(prototype)

  4. 对象的__proto__属性,指向类的原型对象prototype

  5. JavaScript使用prototype链实现继承机制

原型链污染是什么

之前说到foo.__proto__指向的是Foo类的prototype。那么,如果我们修改了foo.__proto__中的值,是不是就可以修改Foo类呢?

做个简单的实验:

// foo是一个简单的JavaScript对象
let foo = {bar: 1}
​
// foo.bar 此时为1
console.log(foo.bar)
​
// 修改foo的原型(即Object)
foo.__proto__.bar = 2
​
// 由于查找顺序的原因,foo.bar仍然是1
console.log(foo.bar)
​
// 此时再用Object创建一个空的zoo对象
let zoo = {}
​
// 查看zoo.bar
console.log(zoo.bar)

最后,虽然zoo是一个空对象{},但zoo.bar的结果居然是2

原因也显而易见:因为前面我们修改了foo的原型foo.__proto__.bar = 2,而foo是一个Object类的实例,所以实际上是修改了Object这个类,给这个类增加了一个属性bar,值为2。

后来,我们又用Object类创建了一个zoo对象let zoo = {},zoo对象自然也有一个bar属性了。

那么,在一个应用中,如果攻击者控制并修改了一个对象的原型,那么将可以影响所有和这个对象来自同一个类、父祖类的对象。这种攻击方式就是原型链污染

mess.js

(function()
{
    var secret = ["aaa","bbb"];
    secret.forEach();
})();

attach.html


    
    

你可能感兴趣的:(原型模式,javascript,开发语言)