JS原型链污染
原理
JavaScript中,类以构造函数的方式来进行定义,test函数的内容就是test类的构造函数,test1是test类的一个实例对象,this.a是test类的一个属性。
JS原型链
JavaScript中,每定义一个函数数据类型,都会自带一个prototype属性,这个属性指向函数的原型对象,并且这个属性是一个对象数据类型的值。
1 | function Father() { |
Son类继承了Father类中的last_name,覆盖了Father类中的first_name。son是Son类的一个实例化对象。Son类的原型prototype指向了Father类。
1 | 实例对象 son.__proto__ 相当于 类 Son.prototpye 具有等价关系,都指向了Father类 |
1 | 原型链:son.__proto__->Son.prototype->Father.prototype->Object.prototype->NULL |
当我们使用一个变量时,该类首先会检测自身,如果不存在,则会沿着原型链递归查找,直到指向NULL。
JS原型链污染
son.__proto__
指向的是Son类的prototype。如果我们修改了son.__proto__
中的值,就可以修改Son类
我们修改了实例化对象son在原型链中的对应的son.__proto__ .__proto__ .__proto__
,实际上是修改了Object这个类,给这个类增加了一个属性test。
当我们用Object类创建了一个test空对象时,该对象就直接含有了一个test属性。
实例
国赛
国赛的时候一道原型链污染的题目
核心代码
1 | function getPlayerDamageValue() //计算纯粹伤害 |
我们就可以通过构造req.body进行原型链污染,在实例化对象tempPlayer的原型__proto__
指向的Object类中加入buff属性,__proto__
可以作为查找键值
其他
哪些情况下我们可以设置__proto__
的值呢?能够控制数组(对象)的“键名”的操作:
- 对象merge
- 对象clone(其实内核就是将待操作的对象merge到一个空对象中)
咕~