js原型链污染初探
Learn from:https://wiki.wgpsec.org/knowledge/ctf/js-prototype-chain-pollution.html
先放一张图
js 是由对象组成的,对象与对象之间存在着继承关系 |
由于对象之间存在继承关系,所以当我们要使用或者输出一个变量就会通过原型链向上搜索,当上层没有就会再向上上层搜索,直到指向 null,若此时还未找到就会返回 undefined
这幅图的原型链是
cat->Cat.protype->Object.prototype->null |
原型链污染通常出现在对象,数组的键名或者属性名可控,同时是赋值语句的情况下 ( 通常使用 json 传值 )
Learn form:https://pazuris.cn/2023/07/26/NodeJs%E5%8E%9F%E5%9E%8B%E9%93%BE%E6%B1%A1%E6%9F%93/
师傅讲的很详细
prototype和__proto__的区别
在 JavaScript 中,每个对象都有一个 __proto__
属性,它指向该对象的原型。原型是一个对象,也可以有自己的原型,这样就形成了一个原型链。同时,每个函数也有一个 prototype
属性,它是一个对象,当该函数作为构造函数创建实例时,实例对象的 __proto__
属性会指向该构造函数的 prototype
属性,这样就可以实现属性和方法的继承。
区别在于:
prototype
属性是函数所独有的,而__proro__
属性是每个对象都有的(再强调一次,函数也是js对象)prototype
属性指向一个对象,它是用来存储属性和方法,这些属性和方法可以被该函数的实例对象所继承。而__proto__
属性指向该对象的原型,它是用来实现对象之间的继承。简单来说就是functionName.prototype===varName.__proto__
,都可以访问到对象的原型。
nodejs原型链污染
概念
一句话概括原型链污染:如果修改了一个对象的原型,那么会影响所有来自于这个原型的对象,这就是原型链污染。
原型链污染通常出现在对象,数组的键名或者属性名可控,同时是赋值语句的情况下 (简单来说就是键名和键值都可控情况下),将键名设置为__proto__
就可以利用赋值语句修改原型对象,进而实现原型链污染,常见的危险函数有merge和clone。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Gu0f3n's blog!