搞网站建设赚钱不,如何改进网站,在外汇管理网站做,免费建立自己的网站前言
在浏览某个论坛的时候#xff0c;第一次看到了JavaScript原型链污染漏洞。当时非常的好奇#xff0c;当时我一直以为js作为一种前端语言#xff0c;就算存在漏洞也是针对前端#xff0c;不会危害到后端#xff0c;因此我以为这种漏洞危害应该不大。可当我看到他的漏…前言
在浏览某个论坛的时候第一次看到了JavaScript原型链污染漏洞。当时非常的好奇当时我一直以为js作为一种前端语言就算存在漏洞也是针对前端不会危害到后端因此我以为这种漏洞危害应该不大。可当我看到他的漏洞危害还有可以执行任意命令的时候发现可能我想到有点简单了。js也是可以用来做后端语言的。这篇文章就来认识一下这个漏洞。
JavaScript原型链是什么
既然漏洞名称是JavaScript原型链污染那么首先就要先明白JavaScript原型链是什么。
正如我们所知Javascrip的复杂类型都是对象类型Object而js不是一门完全面对对象编程的语言。那么对于对象编程来说要考虑对象的继承。
js实现继承的核心就是原型链。我理解的就是原型链的存在就是js中的继承机制保证函数或对象中的方法属性可以向下传递。
js使用了构造函数来创建对象如下我们可以通过构造函数来定义一个类
// 构造函数
function Person(name, age) {this.name name;this.age age;
}// 生成实例
const p new Person(zhangsan, 18); 可以看到这个类除了我们定义的两个属性以外还有一个prototype的属性。prototype指向函数的原型对象这是一个显式原型属性只有函数才拥有该属性。
prototype也拥有两个属性 constructor指向原型的构造函数 prototype指向了Object的原型 在prototype的属性中有一个_proto_那么这个_proto_与prototype又有什么关系 原型prototype是类的一个属性而所有用类实例化的对象都将拥有这个属性中的所有内容包括变量和方法。比如上图中的p对象其天生就具有类Person的属性和方法。
我们可以通过Person.prototype来访问Person类的原型但Person实例化出来的对象是不能通过prototype访问原型的。这时候就该__proto__登场了。
也就是类可以用prototype来访问类的原型而实例化的对象可以用_proto_来访问对象所在类的prototype属性。
总结
其实我们只要明白一点就可以了JavaScript原型链是js中实现继承的核心js的对象都会执行其它的原型最后指向的原型为null。最后关于原型链再来总结一下
1js是通过原型链来实现继承的。
2所有类对象在实例化的时候将会拥有prototype中的属性和方法
3类可以使用prototype来访问类的原型对象而实例化对象可以通过_proto_来访问类的原型对象
let f new Foo();
f.constructor Foo;
f._proto_ Foo.prototype
f._proto_ Foo.prototype
Foo._proto_ Function.prototype
原型链污染
在了解了原型链的相关知识以后可以来看看竟然什么是原型链污染漏洞。
上面说过实例化对象的__proto__指向了类的prototype。那么如果我们修改了实例化对象__proto__中的值是不是就可以修改类中的值呢是否可以影响所有和这个对象来自同一个类、父祖类的对象
其实这就是原型链污染的原理。我们通过修改实例化对象的__proto__中的值污染了类本体进而影响所有和这个对象来自同一个类、父祖类的对象。
p神的博客上有一个这样的例子用来说明原型链污染 实际情况下利用分析
在实际的情况中我们可能只能控制部分参数那么我们怎么才能为__proto__赋值呢
要为__proto__赋值就要求__proto__作为变量传进去并且作为键名这种情况一般出现在下面的三种场景中
对象merge对象clone其实内核就是将待操作的对象merge到一个空对象中路径查找属性然后修改属性的时候
下面借用p神文章中的一个例子来看看具体操作原文链接为深入理解 JavaScript Prototype 污染攻击 | 离别歌
以对象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]}}
}
在合并的过程中存在赋值的操作target[key] source[key]那么这个key如果是__proto__是不是就可以原型链污染呢
let o1 {}
let o2 {a: 1, __proto__: {b: 2}}
merge(o1, o2)
console.log(o1.a, o1.b)o3 {}
console.log(o3.b)
结果是合并虽然成功了但原型链没有被污染 这是因为我们用JavaScript创建o2的过程let o2 {a: 1, __proto__: {b: 2}}中__proto__已经代表o2的原型了此时遍历o2的所有键名你拿到的是[a, b]__proto__并不是一个key自然也不会修改Object的原型。从下面的图中也可以看出在o1中参数b并没有出现在原型中。 那么如何让__proto__被认为是一个键名呢
我们将代码改成如下
let o1 {}
let o2 JSON.parse({a: 1, __proto__: {b: 2}})
merge(o1, o2)
console.log(o1.a, o1.b)o3 {}
console.log(o3.b)
可见新建的o3对象也存在b属性说明Object已经被污染 这是因为JSON解析的情况下__proto__会被认为是一个真正的“键名”而不代表“原型”所以在遍历o2的时候会存在这个键。
再来看看o1发现b属性是定义在原型之中的。 merge操作是最常见可能控制键名的操作也最能被原型链攻击很多常见的库都存在这个问题。
js原型链污染漏洞分析
接下来用一个cve漏洞来具体再看一下这个漏洞。
3.4.0版本之前的jQuery存在一个原型污染漏洞CVE-2019-11358PoC如下。
//代码如下如果从前端接收一个json内容传到后端。
//json内容JSON.parse({__proto__: {z: 123}})const json1 ajax();
jQuery.extend(true, {}, JSON.parse(json1));
console.log( test in {} ); // true
jQuery.extend () 函数用于将一个或多个对象的内容合并到目标对象
$.extend( [deep ], target, object1 [, objectN ] ) 参数 描述 deep 可选。 Boolean类型 指示是否深度合并对象默认为false。如果该值为true且多个对象的某个同名属性也都是对象则该属性对象的属性也将进行合并。 target Object类型 目标对象其他对象的成员属性将被附加到该对象上。 object1 可选。 Object类型 第一个被合并的对象。 objectN 可选。 Object类型 第N个被合并的对象。
再来看看实际的代码是如何去写入的。
首先下载jQuery这里下载的是3.3.0版本
GitHub - jquery/jquery at 3.3.0
在src/core.js中文件中可以找到该extend函数。看过源码可以发现该函数的正好符合上面说的合并数据的概念那么来看看它到底会不会被污染 我们来动态调试一下这个程序
引入jQuery脚本并设置断点进行调试 首先根据第一个参数判断是否进行深度拷贝然后进行第一次循环取得参数为__proto__ 第二次循环在__proto__中去参数进行赋值 此时再看原型已经被污染了 总结
js原型链污染可以说原理并不是太难懂关键是实际中如何去利用。关于这个漏洞也是看了很多大神的文章它们的思路真的太厉害了我还有很多需要学习的跟大家一起共勉。
由于本人水平有限文章中可能会出现一些错误欢迎各位大佬指正感激不尽。如果有什么好的想法也欢迎交流谢谢大家了~~
参考链接
JavaScript原型链污染原理及相关CVE漏洞剖析 - FreeBuf网络安全行业门户
深入理解 JavaScript Prototype 污染攻击 | 离别歌
再探 JavaScript 原型链污染到 RCE - 先知社区
Node.js原型链污染的利用 - FreeBuf网络安全行业门户
最后推荐一款应用开发神器
关于目前低代码在技术领域很活跃 低代码是什么一组数字技术工具平台能基于图形化拖拽、参数化配置等更为高效的方式实现快速构建、数据编排、连接生态、中台服务等。通过少量代码或不用代码实现数字化转型中的场景应用创新。它能缓解甚至解决庞大的市场需求与传统的开发生产力引发的供需关系矛盾问题是数字化转型过程中降本增效趋势下的产物。 一款好用的低代码平台——JNPF快速开发平台。近年在市场表现和产品竞争力方面表现较为突出采用的是最新主流前后分离框架SpringBootMybatis-plusAnt-DesignVue3。代码生成器依赖性低灵活的扩展能力可灵活实现二次开发。
以JNPF为代表的企业级低代码平台为了支撑更高技术要求的应用开发从数据库建模、Web API构建到页面设计与传统软件开发几乎没有差异只是通过低代码可视化模式减少了构建“增删改查”功能的重复劳动还没有了解过低代码的伙伴可以尝试了解一下。
应用https://www.jnpfsoft.com/?csdn
有了它开发人员在开发过程中就可以轻松上手充分利用传统开发模式下积累的经验。所以低代码平台对于程序员来说有着很大帮助。