JavaScript原型链污染

前言

在浏览某个论坛的时候,第一次看到了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);

1692167778_64dc6e62b659f0a4498b9.png!small?1692167779350

可以看到这个类除了我们定义的两个属性以外,还有一个prototype的属性。prototype指向函数的原型对象,这是一个显式原型属性,只有函数才拥有该属性。

prototype也拥有两个属性:

constructor:指向原型的构造函数

prototype:指向了Object的原型

在prototype的属性中有一个_proto_,那么这个_proto_与prototype又有什么关系?

1692167810_64dc6e826449231561148.png!small?1692167811088

原型prototype是类的一个属性,而所有用类实例化的对象,都将拥有这个属性中的所有内容,包括变量和方法。比如上图中的p对象,其天生就具有类Person的属性和方法。

我们可以通过Person.prototype来访问Person类的原型,但Person实例化出来的对象,是不能通过prototype访问原型的。这时候,就该__proto__登场了。

也就是类可以用prototype来访问类的原型,而实例化的对象可以用_proto_来访问对象所在类的prototype属性。

总结:

其实我们只要明白一点就可以了,JavaScript原型链是js中实现继承的核心,js的对象都会执行其它的原型,最后指向的原型为null。最后关于原型链再来总结一下

1)js是通过原型链来实现继承的。

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神的博客上有一个这样的例子,用来说明原型链污染:

1692167987_64dc6f332874455dd5d81.png!small?1692167987836

实际情况下利用分析

在实际的情况中,我们可能只能控制部分参数,那么我们怎么才能为__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)

结果是,合并虽然成功了,但原型链没有被污染:

1692168050_64dc6f7280e79c362a397.png!small?1692168051194

这是因为,我们用JavaScript创建o2的过程(let o2 = {a: 1, "__proto__": {b: 2}})中,__proto__已经代表o2的原型了,此时遍历o2的所有键名,你拿到的是[a, b],__proto__并不是一个key,自然也不会修改Object的原型。从下面的图中也可以看出,在o1中,参数b并没有出现在原型中。

1692168062_64dc6f7e3ea57daf7bf33.png!small?1692168062943

那么,如何让__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已经被污染

1692168090_64dc6f9ae493107bec1d4.png!small?1692168091483

这是因为,JSON解析的情况下,__proto__会被认为是一个真正的“键名”,而不代表“原型”,所以在遍历o2的时候会存在这个键。

再来看看o1发现,b属性是定义在原型之中的。

1692168096_64dc6fa0980dab3967fd7.png!small?1692168097212

merge操作是最常见可能控制键名的操作,也最能被原型链攻击,很多常见的库都存在这个问题。

js原型链污染漏洞分析

接下来用一个cve漏洞来具体再看一下这个漏洞。

3.4.0版本之前的jQuery存在一个原型污染漏洞CVE-2019-11358,PoC如下。

//代码如下,如果从前端接收一个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函数。看过源码,可以发现该函数的正好符合上面说的合并数据的概念,那么来看看它到底会不会被污染?

1692168161_64dc6fe1e3ff617f47974.png!small?1692168162655

我们来动态调试一下这个程序:

引入jQuery脚本,并设置断点,进行调试

1692168167_64dc6fe7b978b4973c2cd.png!small?1692168168393

首先根据第一个参数判断是否进行深度拷贝,然后进行第一次循环,取得参数为__proto__

1692168172_64dc6fecc462985824a7e.png!small?1692168173522

第二次循环,在__proto__中去参数进行赋值

1692168177_64dc6ff18c0335618e4f2.png!small?1692168178185

此时再看原型已经被污染了

1692168182_64dc6ff620c4ded5d0a06.png!small?1692168182716

总结

js原型链污染可以说原理并不是太难懂,关键是实际中如何去利用。关于这个漏洞也是看了很多大神的文章,它们的思路真的太厉害了,我还有很多需要学习的,跟大家一起共勉。

由于本人水平有限,文章中可能会出现一些错误,欢迎各位大佬指正,感激不尽。如果有什么好的想法也欢迎交流,谢谢大家了~~

参考链接

JavaScript原型链污染原理及相关CVE漏洞剖析 - FreeBuf网络安全行业门户

深入理解 JavaScript Prototype 污染攻击 | 离别歌

再探 JavaScript 原型链污染到 RCE - 先知社区

Node.js原型链污染的利用 - FreeBuf网络安全行业门户
 

最后,推荐一款应用开发神器

关于目前低代码在技术领域很活跃!

低代码是什么?一组数字技术工具平台,能基于图形化拖拽、参数化配置等更为高效的方式,实现快速构建、数据编排、连接生态、中台服务等。通过少量代码或不用代码实现数字化转型中的场景应用创新。它能缓解甚至解决庞大的市场需求与传统的开发生产力引发的供需关系矛盾问题,是数字化转型过程中降本增效趋势下的产物。

一款好用的低代码平台——JNPF快速开发平台。近年在市场表现和产品竞争力方面表现较为突出,采的是最新主流前后分离框架(SpringBoot+Mybatis-plus+Ant-Design+Vue3。代码生成器依赖性低,灵活的扩展能力,可灵活实现二次开发。

以JNPF为代表的企业级低代码平台为了支撑更高技术要求的应用开发,从数据库建模、Web API构建到页面设计,与传统软件开发几乎没有差异,只是通过低代码可视化模式,减少了构建“增删改查”功能的重复劳动,还没有了解过低代码的伙伴可以尝试了解一下。

应用:https://www.jnpfsoft.com/?csdn

有了它,开发人员在开发过程中就可以轻松上手,充分利用传统开发模式下积累的经验。所以低代码平台对于程序员来说,有着很大帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/65996.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

简明易懂:Python中的分支与循环

文章目录 前言分支结构if 语句:单一条件判断else语句:提供备选方案elif 语句:多条件判断嵌套的分支结构:复杂条件逻辑 循环结构for循环:遍历序列range()函数与for循环while循环:条件重复循环控制&#xff1…

GA遗传算法

储备知识 GA算法主要解决数学模型中最优化的搜索算法,是进化算法中的一种,基因算法借鉴了自然界基因的遗传的主要现象,分别为遗传,变异,自然选择,杂交等。 GA算法参数 GA算法的参数如下所示。 种群规模…

剑指 Offer 62. 圆圈中最后剩下的数字(简单)

题目&#xff1a; class Solution { public:int lastRemaining(int n, int m) {int pos 0;for(int i2;i<n;i){pos (posm)%i;}return pos;} };作者&#xff1a;想吃火锅的木易 链接&#xff1a;详细题解 来源&#xff1a;力扣&#xff08;LeetCode&#xff09;

ssh常用操作

ssh常用操作 SSH是一种安全协议&#xff0c;ssh是该协议的客户端程序&#xff0c;openssh-server则是该协议的服务端程序 常用系统都自带了ssh客户端程序&#xff0c;服务端程序则可能要安装 密码远程登陆 前提&#xff1a;服务器安装了openssh-server&#xff0c;未安装时…

安装bpftrace和bcc的踩坑记录

最后在Ubuntu22.04使用Ubuntu提供的安装命令完成了安装。这里是记录尝试在Ubuntu18.04和Ubuntu22.04使用源码安装未果的过程。 文章目录 22版本安装bcc准备工具安装命令使用报错&#xff1a;iovisor封装的安装方式ubuntu的安装方式 For Bionic (18.04 LTS)官方提供的源码安装准…

Tutorial: Mathmatical Derivation of Backpropagation

目录 1. 概要 2. Gradient Descent 3. Chain rule 3.1 单变量基本链式法则 3.2 单变量全微分链式法则 3.3 小贴士&#xff1a;微分、导数、导函数是什么关系&#xff1f; 4. What and why backpropagation? 5. Backpropagation for a simple neural network 5.1 基于…

哪些存储设备的数据需要注意,防止误删除或者格式化丢失?

以下是一些存储设备的数据要注意&#xff0c;防止误删除或者格式化丢失&#xff1a; 1.硬盘&#xff1a;存储重要数据时要备份&#xff0c;避免硬盘故障、误格式化等情况导致数据丢失。 2.USB闪存驱动器&#xff1a;在拔出USB闪存驱动器前&#xff0c;应该先进行“安全删除”…

Jmeter(三十一):制造大批量的用户数据数据

需求&#xff1a;因测试需要&#xff0c;要造100w用户数据&#xff0c;通过用户名、手机号、密码可新增用户&#xff0c;其中用户名和电话号码要求100w用户不能重复 要点&#xff1a; 1、通过Bean shell Sampler实现用户名和手机号的足够随机。 符合我们常用规则的手机号&#…

element侧边栏子路由点击不高亮问题

最近自己封装侧边栏 又碰到了点击子路由不高亮的问题 <template><div class"aside"><el-scrollbar :vertical"true" class"scrollbar_left_nav"><el-menu :default-active"defaultActive" :collapse"$stor…

CTFhub-文件上传-.htaccess

首先上传 .htaccess 的文件 .htaccess SetHandler application/x-httpd-php 这段内容的作用是使所有的文件都会被解析为php文件 然后上传1.jpg 的文件 内容为一句话木马 1.jpg <?php echo "PHP Loaded"; eval($_POST[a]); ?> 用蚁剑连接 http://ch…

遗传算法决策变量降维的matlab实现

1.案例背景 1.1遗传算法概述 遗传算法是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法。它最初由美国Michigan大学的J. Holland教授提出,1967年, Holland 教授的学生 Bagley在其博士论文中首次提出了“遗传…

利用frps搭建本地自签名https服务的透传

nginx的搭建就不介绍了&#xff0c;教程很多&#xff0c;基本上油手就会。 在本例中&#xff0c;frp服务器的域名是 www.yourfrp.com&#xff0c;同时也是反向代理nginx服务器; 本地网站要用的域名&#xff1a; test.abcd.com 请事先将 test.abcd.com 解析到 frp所在服务器…

CC1310开发工具下载及环境搭建

目录 CC1310开发工具集 CC1310SDK下载安装注意事项 CCS下载安装注意事项 导入示例代码 CCS常用设置 CC1310是TI的一款sub1G射频模块&#xff0c;具体参数见数据手册吧&#xff08;CC1310数据手册、用户手册下载&#xff1a;https://dev.ti.com/tirex/explore/node?nodeA_…

pdf转换成图片转换器在线怎么转?pdf转换成图片具体方法介绍

很多用户们都是比较喜欢使用pdf文档的&#xff0c;由于这种文件格式的便携性非常高&#xff0c;所以广泛的应用于工作和学习领域&#xff0c;再加上pdf文档可以随意转换成为其他的文件格式&#xff0c;更是让pdf文档受到了更多用户们的欢迎&#xff0c;那么pdf转换成图片转换器…

C++设计模式_02_面向对象设计原则

文章目录 1. 面向对象设计&#xff0c;为什么&#xff1f;2. 重新认识面向对象3. 面向对象设计原则3.1 依赖倒置原则(DIP)3.2 开放封闭原则(OCP )3.3 单一职责原则( SRP )3.4 Liskov 替换原则 ( LSP )3.5 接口隔离原则 ( ISP )3.6 优先使用对象组合&#xff0c;而不是类继承3.7…

光伏瓦屋顶

光伏瓦是由非晶硅材料制成的有光伏电池的屋面板&#xff0c;把光伏组件嵌入支撑结构&#xff0c;使太阳能板和建筑材料结为一体&#xff0c;直接应用于屋顶&#xff0c;和普通屋面瓦一样安装在屋面结构上。然后&#xff0c;光伏材料和组件将光转化为电能&#xff0c;通过吸收太…

操作系统备考学习 day2 (1.3.2 - 1.6)

操作系统备考学习 day2 计算机系统概述操作系统运行环境中断和异常的概念系统调用 操作系统体系结构操作系统引导虚拟机 计算机系统概述 操作系统运行环境 中断和异常的概念 中断的作用 CPU上会运行两种程序&#xff0c;一种是操作系统内核程序&#xff0c;一种是应用程序。…

【原创】H3C三层交换机VLAN路由

网络拓扑图 VLAN 配置 VLAN 100 VLAN 200 [H3C]int vlan 100 ip address 1.1.1.1 255.255.255.0[H3C-Vlan-interface100]int vlan 200 ip address 2.2.2.1 255.255.255.0[H3C]int GigabitEthernet 1/0/1port access vlan 100[H3C]int GigabitEthernet 1/0/2port access vlan 2…

SpringCloudAlibaba常用组件

SpringCloudAlibaba常用组件 微服务概念 1.1 单体、分布式、集群 单体 ⼀个系统业务量很⼩的时候所有的代码都放在⼀个项⽬中就好了&#xff0c;然后这个项⽬部署在⼀台服务器上就 好了。整个项⽬所有的服务都由这台服务器提供。这就是单机结构。 单体应⽤开发简单,部署测试…

数学建模--主成分分析法(PCA)的Python实现(

目录 1.算法核心思想&#xff1a; 2.算法核心代码&#xff1a; 3.算法分类效果&#xff1a; 1.算法核心思想&#xff1a; 1.设置降维后主成分的数目为2 2.进行数据降维 3.设置main_factors1个划分类型 4.根据组分中的值进行分类 5.绘制出对应的图像 2.算法核心代码&#xff1a…