JavaScript Prototype Pollution
JavaScript Prototype Pollution
JavaScript中的原型链污染是指攻击者通过覆盖或修改对象的原型链上的属性,从而改变对象的行为或者访问不应该访问的属性或方法
原型链污染通常发生在JavaScript对象的继承机制中,因为JavaScript是一种基于原型的语言,对象会继承其原型链上的所有属性和方法
JS原型链污染分,客户端原型污染、服务端原型污染
JavaScript 原型
JavaScript 中的原型是一个对象,它在创建新对象时被用来作为新对象的初始属性
1 | username = "" |
原型链实现继承
当一个新对象被创建时,它会从构造函数的 prototype 属性指向的对象那里继承属性和方法
1 | function Parent () { |
prototype & proto
- prototype
prototype是函数对象特有的属性,每个函数都有一个prototype属性,这个prototype属性是一个指向原型对象的指针,它包含了可以由该函数的实例继承的属性和方法- 当你创建一个新的函数时,JavaScript 自动为该函数创建一个
prototype对象,并赋值给prototype属性 - 通过
prototype对象,你可以定义函数的共享属性和方法,它将被该函数的所有实例所共享
- proto
__proto__是每个对象都具有的属性,用于指向其构造函数的原型。它是一个指向该对象的原型链上一层的链接__proto__属性是非标准的,尽管大多数现代浏览器都支持它,但它已经被 ECMAScript 6 标准中的Object.getPrototypeOf方法所替代__proto__主要用于获取和设置对象的原型
1 | const object = {} |
总结一下:
prototype是一个类的属性,所有类对象在实例化的时候将会拥有prototype中的属性和方法- 一个对象的
__proto__属性,指向这个对象所在的类的prototype属性
JSON.parse()
JSON.parse()还将 JSON 对象中的任何键视为任意字符串,包括__proto__这为原型污染提供了一个潜在载体
1 | const objectLiteral = {__proto__: {evilProperty: 'payload'}}; |
Node.js,hasOwnProperty函数用于检查对象自身是否包含指定的属性(即不包括从原型链继承的属性)
原型链污染
哪些情况下我们可以设置__proto__的值呢?其实找找能够控制数组(对象)的“键名”的操作即可:
- 对象merge
- 对象clone(其实内核就是将待操作的对象merge到一个空对象中)
1 | function merge(target, source) { |
example

绕过filter
每个构造函数(constructor)都有一个原型对象(prototype) constructor.prototype ==== __proto__
1 | // 1 |
JSON 空格覆盖
Express 框架提供了一个json spaces选项,使您能够配置用于缩进响应中任何 JSON 数据的空格数
1 | { |