您的位置:首页 > 娱乐 > 八卦 > 视频教程网_php小程序开发完整教程_快速提升关键词排名软件_新东方考研培训机构官网

视频教程网_php小程序开发完整教程_快速提升关键词排名软件_新东方考研培训机构官网

2024/12/23 5:23:02 来源:https://blog.csdn.net/Superstacks/article/details/143657944  浏览:    关键词:视频教程网_php小程序开发完整教程_快速提升关键词排名软件_新东方考研培训机构官网
视频教程网_php小程序开发完整教程_快速提升关键词排名软件_新东方考研培训机构官网
原型链污染是指攻击者通过修改JavaScript对象的原型(prototype),从而影响了基于该原型创建的所有对象的行为。

在JavaScript中,每个对象都有一个指向其原型的内部链接,这个原型本身也可以有它自己的原型,形成了一条原型链。
当访问一个对象的属性时,如果该对象自身没有这个属性,JavaScript引擎会沿着原型链向上查找。

攻击者可能会利用这个机制,通过修改对象的原型来注入恶意属性或方法,进而在应用程序的其他部分执行恶意代码或改变预期行为。
这通常发生在攻击者能够控制或影响对象原型的情况下,比如通过用户输入或某些不安全的操作。

什么是原型链污染

例如之前讲的原型案例:

// 假设我们有一个名为 Alice 的对象,它有一个 greet 方法  
let Alice = {  greet: function() {  console.log("Hello, I'm Alice.");  }  
};  // Alice 调用 greet 方法,输出 "Hello, I'm Alice."  
Alice.greet(); // 输出: Hello, I'm Alice.  // 接下来,攻击者试图通过修改 Alice 的原型来污染原型链  
Alice.__proto__.evilGreet = function() {  console.log("You've been hacked!");  // 这里可以执行更多的恶意代码...  
};  // 攻击者现在创建了一个新的对象 Bob,它基于 Object.prototype(即 Alice 的原型)  
let Bob = {};  // Bob 调用 evilGreet 方法,这是通过原型链污染注入的  
Bob.evilGreet(); // 输出: You've been hacked!  // 更糟糕的是,由于原型链污染,现在所有基于 Object.prototype 创建的对象都继承了这个恶意的 evilGreet 方法  
// 包括 Alice 对象本身(尽管它原本有自己的 greet 方法)  
Alice.evilGreet(); // 输出: You've been hacked!

在这个案例中,攻击者通过向 Alice.__proto__(即 Object.prototype)添加一个新的 evilGreet 方法,成功地污染了原型链。
这不仅影响了新创建的对象 Bob,还影响了原有的 Alice 对象。
即使 Alice 对象原本有自己的 greet 方法,它现在也能访问到通过原型链污染注入的 evilGreet 方法。

原型链污染通常发生在以下几种情况:

  • 不安全的对象合并:当开发者尝试将多个对象合并成一个时,如果没有正确检查和处理原型链上的属性,就可能导致污染。
    例如,如果攻击者能够控制合并操作中的某个对象,并为其添加__proto__属性,那么合并后的对象可能会继承攻击者指定的属性。
  • 使用不安全的库或框架:某些库或框架在处理对象时可能存在漏洞,允许攻击者通过特定输入修改原型链。
  • 用户输入处理不当:如果应用程序没有正确验证和清理用户输入,攻击者可能会构造恶意的输入来修改原型链。

不安全的对象合并

在实际应用中,哪些情况下可能存在原型链能被攻击者修改的情况呢?
我们思考一下,哪些情况下我们可以设置_proto__的值呢?其实找找能够控制数组(对象)的“键名”的操作即可:
。对象merge 结合 拼接
。对象clone(其实内核就是将待操作的对象merge到一个空对象中)复制以对象merge为例,我们想象一个简单的merge函数:

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];}}
}// 假设有一个用户输入的对象  
const userInput = {"name":"alice",__proto__: {  isAdmin: true  }  
};  // 合并对象时,原型链被污染  
merge({}, userInput);  // 所有对象都会继承这个isAdmin属性  
console.log({}.isAdmin); // 输出: undefined

实际上Object输出的是undefined,这是因为,我们用lavaScript创建userInput的过程const userInput = { ... }中,__proto__已经代表userInput的原型了,
此时遍历userInput的所有键名,你拿到的是[name]__proto__并不是一个key自然也不会修改Object的原型。
现在将代码改成:

let userInput =JSON.parse('{"name":"alice","__proto__":{"isAdmin":true}}')
// 合并对象,导致原型链污染  
merge({}, userInput);  
// 正常来说所有对象都会继承这个isAdmin属性  
console.log({}.isAdmin); // 输出: true

这样的话alice对象的原型就被污染了,所有继承自Object.prototype的对象都将具有isAdmin属性 。


总结

系列文章

蓝桥杯-网络安全比赛(5)基础学习-JavaScript原型链
蓝桥杯-网络安全比赛(4)基础学习-JavaScript同步与异步、宏任务与微任务
蓝桥杯-网络安全比赛(3)基础学习- JavaScript的闭包与this
蓝桥杯-网络安全比赛(2)基础学习-正则表达式匹配
蓝桥杯-网络安全比赛(1)基础学习-使用PHP、PYTHON、JAVA

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com