【无标题】

原型链污染

原型污染是一个安全漏洞,非常特定于 JavaScript。它源于 JavaScript 继承模型,称为基于原型的继承。与 C++ 或 Java 不同,在 JavaScript 中,您不需要定义类来创建对象。您只需要使用大括号符号并定义属性

const obj = { prop1: 111, prop2: 222,}

该对象有两个属性:prop1prop2。但这些并不是我们可以访问的唯一属性。例如调用obj.toString()将返回"[object Object]"toString(连同其他一些默认成员)来自原型。JavaScript 中的每个对象都有一个原型(也可以是null)。如果我们不指定它,默认情况下对象的原型是Object.prototype.
简而言之,当我们尝试访问对象的属性时,JS 引擎首先检查对象本身是否包含该属性。如果是,则将其退回。否则,JS 会检查原型是否具有该属性。如果没有,JS 会检查原型的原型……以此类推,直到原型为null. 它被称为[原型链]。

Proto 特性
1、它指的是一个 object 所有 prototype 的特殊属性

2、所有 Objects 的属性 (Prototype) 都是 proto

3、_proto_也是一个 Objects

Object(“对象“)可视作键值对,“键”是字符串,“值”可以是任何内容(类似于其它语言中的 “map” 或 “dictionary”)。你在 JavaScript(除了原语)中输入的所有东西就是一个object。

“prototype (原型)”是和 object 相关的一个属性,用作使 JavaScript objects 互相继承特性的机制。由于JavaScript 中几乎所有一切都是一个 object,因此 prototype 也是一个 object。

一个 Objects Prototype 可能也具有一个 “Prototype”,从中它可继承 prototype 或其它属性等,这种情况被称为“原型链”。

原型污染漏洞何时产生?
当攻击者操纵 proto(通常通过在 proto 上新增一个新的 Prototype方式操纵)时就会发生原型污染。由于每个 object 都存在 proto,而且每个 Objects 都从其 Prototype 中继承 Prototypes,所有 JavaScript Objects 都会通过原型链继承该新增。恶意人员可利用这一能力将属性插入已有 JavaScript 代码中,并通过触发 JavaScript 例外执行拒绝服务攻击,或者通过插入恶意代码的方式实现远程代码执行。

  1. 遍历obj2. 唯一的属性是__proto__
  2. 检查是否obj1.__proto__存在。确实如此。
  3. 遍历obj2.__proto__. 唯一的属性是x
  4. 赋值:obj1.__proto__.x = obj2.__proto__.x。因为obj1.__proto__指向Object.prototype,则原型被污染。

原型链污染的大致过程:

// 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.bar的结果是2;

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

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

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

你可能感兴趣的:(原型模式)