原型链污染初探

2019年初,Snyk的安全研究人员披露了流行的JavaScript库Lodash中一个严重漏洞的详细信息,该漏洞使黑客能够攻击多个Web应用程序,这个安全漏洞就是一个原型污染漏洞(JavaScript Prototype Pollution),攻击者可以利用该漏洞利用JavaScript编程语言的规则并以各种方式破坏应用程序。
与该攻击思想类似的,包括但不限于Python的元对象可同样可能以这样的攻击方式实现攻击
前置知识
原型链
JavaScript 常被描述为一种基于原型的语言 (prototype-based language)——每个对象拥有一个原型对象,对象以其原型为模板、从原型继承方法和属性。每个对象都有一个名为__proto__
的内置属性,它指向该对象的原型。同时,每个函数也都有一个名为 prototype 的属性,它是一个对象,包含构造函数的原型对象应该具有的属性和方法。简单来说,__proto__
属性是指向该对象的原型,而 prototype属性是用于创建该对象的构造函数的原型原型对象也可能拥有原型,并从中继承方法和属性,一层一层、以此类推。这种关系常被称为原型链 (prototype chain)
JavaScript的继承机制
当我们访问某一对象Object的一个的key
属性时,JavaScript会进行一次递归查询,例如:
- 在该对象
Object
中寻找key
属性 - 在该对象中没有找到时,它会在在
Object.__proto__
中寻找key
属性 - 如果仍未找到,此时会去
Object.__proto__.__proto__
中寻找key
属性
漏洞成因
在JavaScript中,每个对象都有一个原型,它是一个指向另一个对象的引用。当我们访问一个对象的属性时,如果该对象没有这个属性,JavaScript引擎会在它的原型对象中查找这个属性。这个过程会一直持续,直到找到该属性或者到达原型链的末尾。
如果攻击者能够控制一个对象的原型,那么将可以影响所有和这个对象来自同一个类、父祖类的对象。这意味着,攻击者可以利用这个特性,通过修改一个对象的原型链,来污染程序的行为。例如,攻击者可以在一个对象的原型链上设置一个恶意的属性或方法,当程序在后续的执行中访问该属性或方法时,就会执行攻击者的恶意代码。
示例
在实际攻击情境中,原型连污染漏洞的情景主要出现在以下两种情况中:
- 对象合并 Merge
- 对象克隆 Clone (本质上是将一个对象合并到空对象中)
以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]
}
}
}
在合并的过程中存在赋值的操作:target[key] = source[key],当key为__proto__时,即可进行原型链污染
由于攻击者需要能攻控制key值,因此原型链污染往往会与JSON解析,模版解析进行反序列化的业务相关联
还有一个经典的原型链污染漏洞可见于参考资料
Bypass
Reference
继承与原型链
关于Prototype Pollution Attack的二三事
高级漏洞篇之原型污染专题
深入理解 JavaScript Prototype 污染攻击
Fuzz中的javascript大小写特性
https://www.freebuf.com/articles/web/361333.html
CVE-2021-25928
JavaScript原型链污染原理及相关CVE漏洞剖析
- Title: 原型链污染初探
- Author: 7erry
- Created at : 2023-10-31 00:00:00
- Updated at : 2023-10-31 00:00:00
- Link: http://7erry.com/2023/10/31/原型链污染初探/
- License: This work is licensed under CC BY-NC 4.0.