You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
function merge(target, source) {
for (let key in source) {
if (key in source && key in target) {
merge(target[key], source[key])
} else {
target[key] = source[key]
}
}
}
代码里面通过merge操作进行原型污染
let o1 = {}
// 这里如果直接使用对象的形式,会不做效,因为 __proto__已经代表o2的原型了,只有使用 JSON.parse 才会被 for in 枚举到
let o2 = JSON.parse('{"a": 1, "__proto__": {"b": 2}}')
merge(o1, o2)
console.log(o1.a, o1.b)
o3 = {}
console.log(o3.b) //-> 2
常见的前端安全有 XSS、CSRF、恶意第三方库这几种,偶然发现了另外一种利用语言特性进行的攻击手段 -- 原型链污染。
既然是原型链污染,那就需要来说明下一个对象上面都有什么属性。
对于一个我们直接声明或者是通过 new Object 而来的对象,proto 会指向 Object.prototype 。
根据 javascript 的属性读取规则,在原实例上查找不到的属性,会顺着原型链往下寻找,最终会找到 Object.prototype。
所以这里只要有办法对 proto 动手脚,那么就可以成功污染到所有从Object继承而来的对象。
实际操作
在实际应用中,哪些情况下可能存在原型链能被攻击者修改的情况呢?
哪些情况下我们可以设置__proto__的值呢?其实找找能够控制数组(对象)的“键名”的操作即可:
一件简单粗暴的 merge 方法
代码里面通过merge操作进行原型污染
所以在实践中要关注 merge方法的实现和使用,对用户传进来的参数要做好校验。比如在3.x版本 express 框架支持根据 Content-Type 来解析请求 Body,这里面就是用到了 JSON.parse 对参数进行对象转换,然后在进行对象合并,这里面就很容易进行原型链攻击。
The text was updated successfully, but these errors were encountered: