直接禁用pickle.loads、yaml.load和带object_hook的json.loads是最有效修复动作,因其不校验类名、不隔离环境、反序列化即执行任意代码,且yaml.load默认FullLoader和json.object_hook均构成RCE高危入口。

直接禁用 pickle.loads、yaml.load 和带 object_hook 的 json.loads,是修复 Python Web 应用不安全反序列化漏洞最有效、最优先的动作。
为什么不能用 pickle.loads 处理用户输入
它不校验类名、不隔离环境、不设沙箱,反序列化即执行任意代码。攻击者只需构造一个含 __reduce__ 方法的对象,就能调用 os.system、eval 或任意模块函数。
- 常见错误现象:
request.data或request.files直接喂给pickle.loads;或在 Celery 任务参数、Redis 缓存值、API body 中隐式调用 - 所有
import pickle和pickle.loads(调用点必须人工审计,重点检查 API 路由、文件上传接口、配置加载逻辑 - 临时加固可加
sys.modules['pickle'] = None,但仅限确认无内部依赖场景(如未用joblib、dill) - 若必须跨进程传对象(如 Celery),改用
task_serializer='json',并确保 payload 是基础类型(dict/list/str等)
yaml.load 必须全部替换为 yaml.safe_load
旧版 yaml.load 默认使用 FullLoader,允许实例化任意 Python 类(如 !!python/object:subprocess.Popen),是 RCE 高发入口。
- 全局搜索
yaml.load(,包括间接调用:Django 的config.from_yaml、Flask 扩展、自定义配置解析器 - PyYAML ≥ 5.1 虽默认指向
SafeLoader,但显式写Loader=yaml.Loader仍会绕过,必须删掉 - 如需支持自定义标签,只能继承
yaml.SafeLoader并手动注册白名单构造器,禁止使用yaml.UnsafeLoader或yaml.CLoader直连用户输入
警惕 json.loads 的 object_hook 回调
JSON 本身安全,但 object_hook 会在每个 dict 解析后触发回调——一旦回调函数含命令执行逻辑(如调用 eval、exec、os.popen),就构成完整 RCE 链。
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
立即学习“Python免费学习笔记(深入)”;
- 审查所有带
object_hook=或object_pairs_hook=的json.loads调用,尤其 ORM 模型反序列化(如 SQLAlchemy 的 JSON 字段解析) - 避免在 hook 中调用不可信方法;若必须构造对象,改用
pydantic.BaseModel.parse_raw(..., strict=True)或dataclasses.asdict - 遇到
JSONDecodeError应直接拒绝请求,不要 fallback 到pickle.loads—— 这种“兜底”反而引入高危路径
别把 joblib 当成 pickle 的安全替代品
joblib 底层仍依赖 pickle(尤其 protocol 4+),默认不做签名、不校验来源,对不可信输入同样危险。
- 典型误用:把 HTTP 请求体、URL 参数、Redis value 交给
joblib.loads—— 和直接用pickle.loads几乎等价 -
joblib合理用途仅限本地:保存 sklearn 模型、缓存 numpy 数组、跨进程传递预处理结果 - 若真需网络传输
joblib数据,必须加 HMAC 签名:hmac.new(KEY, data, hashlib.sha256).digest(),且服务端验证通过后再解包
真正难处理的不是“怎么换库”,而是那些你控制数据生成端却无法彻底禁用反序列化的场景(比如 Celery 内部 RPC、Django 缓存中的类实例)。这时候,硬编码白名单比任何外围加固都管用——重写 pickle.Unpickler.find_class,只放行 datetime.datetime、numpy.ndarray 这类无副作用的基础类,其余一律抛 AttributeError。

















