JS原型链污染
JS 原型链污染
参考连接:
一文搞懂JS原型与原型链(超详细,建议收藏) - 掘金 (juejin.cn)
js原型链污染(超详细)_javascript原型链污染_l_abour的博客-CSDN博客
前置知识
-
JS的复杂类型都是对象类型(Object),作为不是完全的面对对象编程的语言,需要使用构造函数进行继承的机制
例子:
1
2
3
4
5
6
7
8// 构造函数
function Person(name, age) {
this.name = name;
this.age = age;
}
// 生成实例
const p = new Person('zhangsan', 18); -
对于无法共享公共属性的问题,使用
原型对象
,来存储这个构造函数
的公共属性以及方法。(主角登场) -
构造函数的
prototype
以及每个通过构造函数
创建出来的实例对象
,其本身有个属性__proto__
,这个属性会指向该实例对象
的构造函数
的原型对象
就是说如图所示
1 | function Preson(name, age) { |
利用
基于上述原理,存在的漏洞点是不安全的对象递归合并,只有不安全的递归合并函数才会导致原型链污染,非递归的算法是不会导致原型链污染的
1 | function merge(target, source) { |
注意:let o2 = {a: 1, “__proto__
”: {b: 2}}中的proto已经作为的是o2的原型,也就是说这里o2[__proto__
]={b:2}(一个对象)并没有被解析成为键名,所以需要JSON.parse将其转成json格式
第一步o1[‘a’]=o2[‘a’]
第二步,会将__proto__
当作键值来看,然后进入if语句中,然后o1['__proto__']['b']=o2['__proto__']['b']
,然后相当于o1.__proto__.b=2
成功污染