原型链污染
原型:
每个 JavaScript 对象都有一个内部属性 [[Prototype]],可通过 proto 或 Object.getPrototypeOf() 访问,它指向另一个对象 —— 这个被指向的对象就是它的“原型”。
proto:
obj.proto 就是 obj 的原型——它指向 obj 所继承的对象
__proto__不是普通属性
const obj = { __proto__: { x: 1 } };
// 这不会改变 obj 的原型
// 只会创建一个名为 "__proto__" 的普通属性(安全性行为)
可以通过复制改变原型
const obj = {};
obj.__proto__ = { isAdmin: true }; //真的修改了原型
console.log({}.isAdmin); // true 所有对象的isAdmin都是true!
原型链
当访问一个对象的属性时:
JS 先在对象自身找;
找不到,就去它的原型找;
还找不到,就去原型的原型找……
直到 Object.prototype(顶层原型);
再往上就是终点 null。null无法被赋予属性
这个链条就叫原型链
辨析继承:
继承在 JavaScript 里不是复制,而是委托查找。
这涉及的原因是为了减少对内存的依赖,以提高性能
继承给了对象一个可以向上翻抽屉的能力
函数的继承:
.prototype
这是函数的一个普通属性,专门用来在 new 时,作为新对象的 [[Prototype]]
原型链污染示例
一个网站的登陆页面

utils/common.js源码泄露

分析
copy函数没有做过滤操作,可尝试__proto__污染
login.js源码泄露

分析
如果secert.ctf==='i-love-freedom'那么能得到了flag
secert类为空,直接继承Object
user类为空,直接继承Object
secert不可控,user可由用户传入并且被执行copy方法,可控
通过user对Object进行污染,使secert.ctf=i-love-freedom
操作
对登陆页面抓包

修改为

获得目标响应

——————————————————————————————————————————————
疑问:__proto__不是普通属性,为什么任然污染成功?
login.js中的
router.post('/', require('body-parser').json(),function(req, res, next)
已经声明了json格式接收
json解析的情况下,__proto__会被认为是一个真正的键名)

浙公网安备 33010602011771号