Lodash原型污染漏洞原理详解

文中涉及操作均来自靶场,切勿用于非授权渗透测试!

一、JavaScript原型链基础

要理解原型污染漏洞,首先需要掌握JavaScript中原型(prototype)和原型链(prototype chain)的基本概念。

1.1 什么是原型

JavaScript是一种基于原型的语言,每个对象都有一个原型对象,对象以其原型为模板,从原型继承方法和属性。原型对象也可能拥有原型,并从中继承方法和属性,这种关系被称为原型链。

function Person(name, age) {this.name = name;this.age = age;
}let p1 = new Person('Alice', 25);
console.log(p1);

在这个例子中,p1Person构造函数的一个实例,它拥有nameage属性,同时还有一个__proto__属性指向Person.prototype

原型链关系验证

console.log(p1.__proto__ === Person.prototype);  // true ✅

console.log(p1.__proto__.__proto__ === Object.prototype);  // true ✅

console.log(p1.__proto__.__proto__.__proto__);  // null ✅

原型链图示

关键点说明

第一层:p1.__proto__ 指向 Person.prototype,这是构造函数为所有实例提供的共享原型对象

第二层:Person.prototype 本身也是一个对象,它的 __proto__ 自然指向 JavaScript 的根原型 Object.prototype

终点:所有原型链最终都会通过 Object.prototype.__proto__ 指向 null,这是原型链的终点

特别说明

在ES6中更推荐使用 Object.getPrototypeOf() 而不是直接访问 __proto__

console.log(Object.getPrototypeOf(p1) === Person.prototype); // true

构造函数本身的 __proto__ 指向 Function.prototype(这是另一个独立的原型链):

console.log(Person.__proto__ === Function.prototype); // true

1.2 所有函数都是 Function 的实例

Person 是构造函数

当你定义 function Person() {}Person 就是一个用于创建对象的构造函数。

但它同时也是一个函数对象,因此它继承自 Function.prototype

console.log(Person.__proto__ === Function.prototype); // true

Function 自身也是构造函数

Function 是 JavaScript 内置的构造函数,用于创建所有函数(包括它自己!)。

有趣的是,Function__proto__ 也指向 Function.prototype

console.log(Function.__proto__ === Function.prototype); // true

这是 JavaScript 中唯一一个 __proto__ 指向自身 prototype 的构造函数。

1.3 Object 的构造函数角色

Object 是顶级构造函数

Object 是所有对象的基类(包括函数对象)。

普通对象(如 {}new Person())的原型链最终都会指向 Object.prototype

ObjectFunction 的关系

Object 本身是一个函数(构造函数),因此它也继承自 Function.prototype

console.log(Object.__proto__ === Function.prototype); // true

Function.prototype 本身是一个对象,它的 __proto__ 又指向 Object.prototype

console.log(Function.prototype.__proto__ === Object.prototype);

1.4 完整的原型链关系图

function Person() {}
const p1 = new Person();// 1. 实例的原型链
console.log(p1.__proto__ === Person.prototype);          // true
console.log(p1.__proto__.__proto__ === Object.prototype); // true
console.log(p1.__proto__.__proto__.__proto__ === null);   // true// 2. 构造函数的原型链
console.log(Person.__proto__ === Function.prototype);     // true
console.log(Function.__proto__ === Function.prototype);   // true (特殊!)
console.log(Object.__proto__ === Function.prototype);     // true// 3. 原型对象的原型链
console.log(Function.prototype.__proto__ === Object.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype);   // true
终极关系总结(关键记忆点)
对象	              __proto__ 指向	        说明
p1 (实例)	          Person.prototype	    实例指向构造函数的原型
Person (函数)	      Function.prototype	  所有函数继承自 Function
Person.prototype	  Object.prototype	    默认构造函数的原型继承自 Object
Function	          Function.prototype	  唯一自引用的构造函数
Object	            Function.prototype	  Object 本身是函数
Function.prototype	Object.prototype	    函数原型的父级是对象原型
Object.prototype	  null	                原型链的终点

二、原型污染漏洞原理

2.1 什么是原型污染

原型污染是指攻击者通过某种手段修改JavaScript对象的原型(通常是Object.prototype),从而影响所有基于该原型的对象的行为。

在Lodash的案例中,某些函数(如defaultsDeep)未能正确处理特殊属性(如constructor__proto__),导致攻击者可以通过精心构造的输入修改Object.prototype

2.2 Lodash漏洞示例

Lodash的defaultsDeep函数用于递归合并对象的属性。在4.17.12之前的版本中,它存在原型污染漏洞:

 const payload = '{"constructor": {"prototype": {"vuln": true}}}';_.defaultsDeep({}, JSON.parse(payload));if({}.vuln === true) {alert('lodash 存在原型污染漏洞!');}else{console.log('no vuln!');}

2.3 解析_.defaultsDeep 为何会导致漏洞

当执行_.defaultsDeep({}, JSON.parse(payload));,递归地将 payload 的属性合并到空对象 {} 中。Lodash 未对特殊属性名(constructorprototype)做安全过滤。

执行流程:
1. 创建恶意对象
const payload = '{"constructor": {"prototype": {"vuln": true}}}';
2. _.defaultsDeep({}, JSON.parse(payload))的过程

_.defaultsDeep(object, sources) 是 Lodash 提供的一个递归合并方法,用于将 sources(源对象)的属性深度合并到 object(目标对象)中,但仅当目标对象的对应属性为 undefined 时才覆盖。

JSON.parse(payload)解析 JSON 字符串,生成 JavaScript 对象

源对象 sources:{ constructor: { prototype: { vuln: true } } }

目标对象 object: 空对象 {}(所有属性初始为 undefined

关键点:constructor.prototype 是 JavaScript 中访问 Object.prototype 的路径。

  1. 合并过程

检查目标对象的 constructor 属性 → undefined,直接合并源对象的 constructor

递归检查 constructor.prototype → 目标对象无此属性,继续合并。

最终将 { vuln: true } 赋值到 Object.prototype(即 constructor.prototype 指向的原型对象)。

2.4 漏洞危害

原型污染可能导致多种安全问题:

属性注入:向全局对象注入恶意属性

拒绝服务(DoS):覆盖关键方法导致应用崩溃

远程代码执行(RCE):在某些特定环境下可导致代码执行

安全机制绕过:可能绕过输入验证或其他安全控制

## 感谢您的关注

echo "QmlsaWJpbGkgc2VhcmNoICdQZW5UZXN0M3JfWmVybGsnIGZvciBtb3JlIHZpZGVvLCBUaGFuayB5
b3UgZm9yIHlvdXIgc3VwcG9ydCEK"|base64 -d

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

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

相关文章

django 获取当前时间 格式 YYYY-MM-DD HH:Mm:ss

在 Django 中获取当前时间并以特定的格式显示,你可以使用 Python 的 datetime 模块结合 Django 的 timezone 模块。这里有两种主要的方法来做到这一点: 方法1:使用 datetime 和 timezone 首先,确保你已经导入了必要的模块&#x…

k8s使用自建nfs做持久化无法控制磁盘使用大小问题处理

如题,创建的pvc并无法控制用户实际使用多少nfs存储,使用xfs_quota来对用户nfs目录做磁盘配额管理 1、需使用xfs文件系统 2、/etc/fstab挂载中开启prjquota(项目配额) 具体操作如下 xfs_quota 使用说明/etc/fstab挂载磁盘 UUID&…

小结:Spring AOP 切点表达式

Spring AOP 切点表达式(Pointcut Expression) 一、切点表达式概述 切点表达式 是 Spring AOP 用于定义哪些方法(或连接点)需要被拦截的规则,主要基于 AspectJ 切点表达式语言。Spring AOP 仅支持方法级别的切点&#…

Linux开发工具之VsCode(Filezila、MobaXterm、Vim三合一)

文章的目的是记录,编程过程中用到的高效工具Vscode。通过这个工具实现了Filezila、MobaXterm、Vim三个工具文件下载上传,终端调试,文件编辑的功能,避免切换和记录指令,效率提升100%。 Linux C到Android App开发推荐链接…

用idea进行数据同步

声明对列和交换机 你需要先在yaml文件当中进行rabbitmq的相关配置 rabbitmq:host:192.168.150.101 //消息件的地址port:5672 //端口数据username:itcast //用户名password:123321 //密码virtual-host:/ //虚拟…

实战:Java web应用性能分析之【异步日志:性能优化的金钥匙】

概叙 实战:Java web应用性能分析之【Arthas性能分析trace监控后端性能】-CSDN博客 在优化方面,可以采取以下步骤: ‌性能分析工具‌:使用Arthas或Async Profiler进行实时诊断,定位耗时的方法调用。这可以帮助精确找…

Puppeteer API

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】

【机器学习】Teacher-Student框架

Teacher-Student Setup是一个经典的机器学习框架,包含两个核心角色: 教师模型 (Teacher Model): 通常是一个更大、更强、已经训练好(或正在训练)的模型。它对问题有很好的理解,性能优秀。它的作用是为学生提…

华为云Flexus+DeepSeek征文|体验华为云ModelArts快速搭建Dify-LLM应用开发平台并创建联网大模型

华为云FlexusDeepSeek征文|体验华为云ModelArts快速搭建Dify-LLM应用开发平台并创建联网大模型 什么是华为云ModelArts 华为云ModelArts ModelArts是华为云提供的全流程AI开发平台,覆盖从数据准备到模型部署的全生命周期管理,帮助企业和开发…

Web API 路径设计哪家强

本文档主要比较一下各家API的URL路径设计,通过学习各家API的URL路径设计,加深对 REST API 的理解,帮助我们设计出更符合 REST 风格的 API。 Google API 文档地址:https://developers.google.com/apis-explorer/#p/ YouTube Dat…

微信小程序中的计算属性库-miniprogram-computed

miniprogram-computed 是一个用于微信小程序的扩展库,它提供了计算属性(computed)和监听器(watch)的功能,类似于 Vue.js 中的计算属性和监听器。以下是使用 miniprogram-computed 的详细步骤: …

【CSS-7】深入解析CSS伪类:从基础到高级应用

CSS伪类是前端开发中不可或缺的强大工具,它们允许我们根据文档树之外的信息或简单选择器无法表达的状态来样式化元素。本文将全面探讨CSS伪类的各种类型、使用场景和最佳实践。 1. 伪类基础概念 1.1 什么是伪类? 伪类(Pseudo-class&#x…

蓝桥杯国赛训练 day4

目录 再创新高 蓝桥大使 表演赛 次数差 再创新高 import java.math.*; import java.util.*;public class Main {static Scanner sc new Scanner(System.in);public static void main(String[] args) {int t 1; // tsc.nextInt();for(int i0;i<t;i) {solve();}} p…

java 高并发设计

文章目录 目录 文章目录 前言 一、通用设计 一、动静分离 二、数据库独立部署 三、问题 1.高并发通用设计方法 2.高并发系统的拆分顺序 二、计算资源高并发 三、网络资源高并发 超高性能场景&#xff08;10万 QPS&#xff09; 中小规模场景&#xff08;5万 QPS以下&a…

docker compose搭建elk 8.6.2

环境搭建 选用版本是比较新的版本 (ELK) 8.6.2 &#xff0c;elk的环境做的还是比较好的又windows和Linux多个版本&#xff0c;并且开箱即用。本地直接下载官方软件也是可以的。最近在学习docker compose&#xff0c;就使用这个环境搭建一下。 前置条件 安装好docker和 docke…

Springboot3+的id字符串转化问题

以下是纯后端实现 Long/BigInteger ID 转为 JSON 字符串 的详细配置方案&#xff0c;基于 Spring Boot 3 和 SpringDoc (OpenAPI) 最新实践 ✨ 1. 添加依赖 确保你的 pom.xml&#xff08;或 Gradle&#xff09;中包含&#xff1a; <dependency><groupId>com.fast…

C#学习第30天: 匹配模式

模式匹配&#xff08;Pattern Matching&#xff09;是 C# 中一个强大且灵活的特性&#xff0c;允许开发者以更直观的方式检查数据结构&#xff0c;并根据特定模式执行操作。 随着 C# 语言版本的发展&#xff0c;模式匹配的功能越来越丰富&#xff0c;为处理复杂数据提供了极大…

SQL进阶之旅 Day 29:NoSQL结合使用策略

【SQL进阶之旅 Day 29】NoSQL结合使用策略 文章简述 随着数据量的激增和业务场景的复杂化&#xff0c;传统关系型数据库在某些场景下已难以满足高性能、高扩展性和灵活数据结构的需求。NoSQL&#xff08;非关系型数据库&#xff09;以其高可扩展性、灵活的数据模型和分布式架构…

PostgreSQL 对 IPv6 的支持情况

PostgreSQL 对 IPv6 的支持情况 PostgreSQL 全面支持 IPv6 网络协议&#xff0c;包括连接、存储和操作 IPv6 地址。以下是详细说明&#xff1a; 一、网络连接支持 1. 监听 IPv6 连接 在 postgresql.conf 中配置&#xff1a; listen_addresses 0.0.0.0,:: # 监听所有IPv4…

模板字符串使用点击事件【VUE3】

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 项目中使用模板字符串的时候很多&#xff0c;有些时候需要再模板字符串中使用点击事件&#xff0c;那么在模板字符串中可以使用点击事件么&#xff1f;如果这个点击事件需要传参呢&#xff1f; 答案…