python原型链污染
字数 1899 2025-08-29 22:41:24
Python原型链污染与Flask安全漏洞分析
1. Python原型链污染基础
1.1 Python中的魔术方法
Python中所有以双下划线__包围的方法称为魔术方法(Magic Method),它们会在特定条件下自动执行:
__class__: 查看变量所属的类__init__(): 类的构造函数,创建实例时自动调用__globals__: 保存函数全局变量的字典引用,可以修改无继承关系的类属性甚至全局变量__file__: 全局变量,返回当前文件路径
1.2 原型链污染原理
在Node.js中,对象的__proto__属性指向该对象所在类的prototype属性。修改son.__proto__中的值可以影响父类。
在Python中,通过修改魔术方法或特殊属性,可以达到类似原型链污染的效果,影响类的行为或全局配置。
2. Flask框架中的安全漏洞
2.1 文件路径污染
通过污染__file__全局变量,可以改变文件路径解析行为。常见的Linux环境变量路径包括:
/proc/[pid]/environ: 当前进程环境变量/etc/environment: 系统全局环境变量
2.2 Flask全局变量
Flask框架中两个重要的全局变量:
-
app: Flask应用实例,核心对象,负责处理请求和配置- 包含路由定义(
app.route) - 应用启动(
app.run()) - 其他配置方法
- 包含路由定义(
-
_static_folder: 指定静态文件目录路径- 默认在应用根目录下的
static文件夹 - 可通过
app.static_folder访问和修改
- 默认在应用根目录下的
2.3 静态目录利用
如果_static_folder被设置为根目录/,可以通过/static/proc/1/environ访问系统环境变量文件。
3. Flask调试模式PIN码攻击
当Flask开启debug模式时,访问/console路由需要PIN码进行调试。PIN码生成依赖六个要素:
- username: 通过
getpass.getuser()或/etc/passwd获取 - modname: 默认
flask.app,通过getattr(mod, "file", None)获取 - appname: 默认
Flask,通过getattr(app, "name", type(app).name)获取 - moddir: Flask库
app.py的绝对路径 - uuidnode: MAC地址十进制表示
- 通过
uuid.getnode()获取 - 或从
/sys/class/net/eth0/address读取16进制后转换
- 通过
- machine_id: 机器唯一标识
- Linux:
/etc/machine-id或/proc/sys/kernel/random/boot_id - Docker:
/proc/self/cgroup中/docker/后的内容
- Linux:
PIN码生成算法:
- Python 3.6: MD5加密
- Python 3.8: SHA1加密
4. 实际攻击案例分析
4.1 污染app.secret_key
通过原型链污染修改Flask的app.secret_key,可以控制会话签名密钥,可能导致会话伪造。
4.2 merge函数漏洞分析
merge函数实现对象合并功能时,如果没有正确处理属性访问,可能导致原型链污染:
def merge(target, source):
for key in source:
if key in target and isinstance(target[key], dict) and isinstance(source[key], dict):
merge(target[key], source[key])
else:
target[key] = source[key]
攻击者可以通过精心构造的输入修改对象的特殊属性。
4.3 WAF绕过技术
- Unicode编码绕过: 使用Unicode编码特殊字符绕过字符串过滤,
json.loads可以解析Unicode - UTF-16BE编码: 将payload编码为UTF-16BE绕过某些过滤机制
4.4 XXE漏洞组合攻击
通过原型链污染设置app.config['xml_data']为恶意XML代码,再访问触发XML解析的路由,实现XXE文件读取。
5. 防御措施
- 严格输入验证: 对所有用户输入进行严格验证和过滤
- 禁用调试模式: 生产环境务必关闭Flask调试模式
- 最小权限原则: 应用运行使用最小必要权限
- 安全配置:
- 限制静态目录访问范围
- 使用随机强密钥
- 代码审计: 检查所有对象合并、属性复制操作的安全性
- 依赖更新: 保持框架和依赖库的最新版本