原型链污染

原型:

每个 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]]

原型链污染示例

一个网站的登陆页面

屏幕截图 2025-12-14 200759

utils/common.js源码泄露

屏幕截图 2025-12-14 200014
分析

copy函数没有做过滤操作,可尝试__proto__污染

login.js源码泄露

屏幕截图 2025-12-14 194821

分析

如果secert.ctf==='i-love-freedom'那么能得到了flag

secert类为空,直接继承Object

user类为空,直接继承Object

secert不可控,user可由用户传入并且被执行copy方法,可控

通过user对Object进行污染,使secert.ctf=i-love-freedom

操作
对登陆页面抓包

屏幕截图 2025-12-14 201049

修改为

屏幕截图 2025-12-14 202706
获得目标响应

屏幕截图 2025-12-14 202634

——————————————————————————————————————————————

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

posted @ 2025-12-14 20:41  yeswind野风  阅读(67)  评论(1)    收藏  举报