当前位置: 首页 > news >正文

Python原型链污染从基础到深入

之前看过许多有关Python原型链污染的题,自己一道也没能做出。

于是今天下定决心好好把这个问题解决一下

1.什么是Python原型链污染?

Python原型链污染是一种通过修改对象原型链中的属性,导致程序行为偏离预期的攻击技术。其核心原理与JavaScript原型链污染类似,但实现方式因语言特性而有所差异。

  • ​原型继承特性​
    Python中每个对象通过__class__属性指向其所属类,类通过__base__属性指向父类。当访问对象属性时,若当前对象/类中未定义,会沿原型链向上查找1****4
  • ​污染条件​
    需要存在递归合并函数(如merge)且未对特殊属性过滤

接下来我们来看一个最简单的原型链污染

class Config:is_admin = Falsedef set_config(cls, key, value):setattr(cls, key, value)def get_config(cls, key):return getattr(cls, key, None)
instance=Config()
print(instance.is_admin)     #False
setattr(instance,'is_admin','True')
print(instance.is_admin)     #True

进入python的debug模式,给倒数三行打上断点。我们可以看到刚初始化的instance里面的is_admin为false

经过setattr函数后is_admin变成了true

这个就是最简单的原型链污染

接下来我们看看一段示例代码

from flask import Flask, request, jsonify
from config import Config
app = Flask(__name__)
@app.route('/update_config',</span> methods=['POST'])
def update_config():data = request.jsonfor key, value in data.items():Config.set_config(key, value)return jsonify({"status": "success", "config": data})
@app.route('/check_admin',</span> methods=['GET'])
def check_admin():is_admin = Config.get_config('is_admin')return jsonify({"is_admin": is_admin})
if __name__ == '__main__':app.run(debug=True)

如果传入恶意参数将is_admin污染为true则可以实现对管理员校验的绕过

因为没有对传入参数进行校验我们可以试图传入{"is_admin":True}

setattr()函数就会把is_admin参数污染为true

实战中我们更经常看到的是merge的合并函数

class father:secret = "hello"
class son_a(father):pass
class son_b(father):pass
def merge(src, dst):for k, v in src.items():if hasattr(dst, '__getitem__'):if dst.get(k) and type(v) == dict:merge(v, dst.get(k))else:dst[k] = velif hasattr(dst, k) and type(v) == dict:merge(v, getattr(dst, k))else:setattr(dst, k, v)
instance = son_b()
payload = {"__class__" : {"__base__" : {"secret" : "world"}}
}
print(son_a.secret)#hello
print(instance.secret)#hello
merge(payload, instance)#hello
print(son_a.secret)#world
print(instance.secret)#world

这里由于个人觉得这个函数比较绕,我们打上断点来一步一步的解析这个函数

刚进入循环时候对应的值,整个阶段我们注意下dst变量的变化

此时dst还是son_b

在经过判断语句后(进入elif分支,因为dst没有__getitem__属性)

此时我们将第二次进入merge函数

进入后:

我们发现dst变成了son_b.__class__而src则是{'base': {'secret': 'world'}}

这是因为getattr函数获取了son_b的class属性,也就是son_b.class

src则是之前的v

继续进行分支的判断,我们即将第三次进入merge函数

进入后:

和之前类似,获取了son_b的class的base属性,相当于son_b.class.__base__也就是father类

第三次循环的k和v

此时的v不是字典了,所以进入了else分支

到了setattr函数了

此时dst为father,k为secret,v为world

所以我们将father类的secret属性成功污染为了world

参考:https://www.7ntsec.cn/?p=56

https://xz.aliyun.com/news/12518

http://www.jsqmd.com/news/31295/

相关文章:

  • 2025 年 11 月中小企业财税合规服务权威推荐榜:专业筹划与风险防控口碑之选
  • 2025 年 11 月财税合规平台推荐榜单:平台报送财税合规,企业财税合规,财税合规服务,专业财税合规平台公司精选指南
  • 11月4号到11月9号的计划安排
  • RCE漏洞基础以及绕过
  • 详细介绍:数据结构:树
  • SQL注入基础及绕过手段
  • WPF实现组件拖动(Grid)
  • 关于嵌入式硬件需要了解的基础知识 - 教程
  • spring-boot-actuator-Health原理
  • 2025年广州防霉检测机构权威推荐榜单:除螨检测/除臭效果测试/输配水设备检测源头机构精选
  • 2025年钣金机箱外壳加工厂家权威推荐榜单:钣金壳体/变频器钣金壳体/钣金加工壳体源头厂家精选
  • 从零到一:我的开源AI商业化实战之路
  • 机器学习 BASEML到底是什么
  • 体育馆游泳卡押金原路退回,安心无忧—东方仙盟 - 指南
  • DesignSpark Mechanical (DSM)输入用户名密码提示在注册过程中发生错误
  • 字段(辨析:字段、对象、属性和方法在 JavaScript 中的关系)
  • P14364 [CSP-S 2025] 员工招聘 / employ 笔记
  • Spring boot 使用虚拟线程示例
  • 微算法科技(NASDAQ MLGO):以隐私计算区块链筑牢多方安全计算(MPC)安全防线
  • 怎么把idea的目录结构,以文本形式输出?——idea使用tree
  • 2025年11月沼气直燃厂家综合评测:徐州海德测控技术有限公司领跑
  • 微信小程序初始配置
  • python爬虫scrapy框架使用 - 教程
  • 2025年塑烧板除尘器源头厂家权威推荐榜单:耐高温除尘器/防爆除尘器/不锈钢除尘器源头厂家精选
  • 2025年剪叉升降平台供应商权威推荐榜单:车载剪叉式升降平台/移动剪叉式升降平台车/轨道升降平台源头厂家精选
  • 第180天:横向移动篇入口切换SMB共享WMI管道DCOM组件Impacket套件CS插件
  • 2025年11月沼气直燃品牌/品牌排名前十:技术实力对比与总结
  • 高效学习方式——知识关联性
  • 基于时间的ACL - 教程
  • 2025年云南做楼体灯光亮化服务商权威推荐榜单:云南做酒店灯光亮化/云南做居民楼灯光亮化/云南做写字楼灯光亮化服务商精选