不可信反序列化为何危险
Python 网络安全自查入门:从常见风险到基础防护步骤
把一段来源不明的字节流恢复成对象,表面上只是"解析数据",实际上是在自己的进程里重建状态。它与读取文本的根本差别在于:反序列化必须决定创建什么类型、调用哪些恢复逻辑,而这些决定的依据来自数据本身。一旦来源不可信,攻击者控制的就不再只是字段的取值,而是程序在恢复过程中会走到哪些代码路径。
风险发生在加载那一刻
常规的输入校验都写在业务逻辑里:先拿到对象,再判断字段是否合法。但对不可信的序列化数据而言,危害往往在对象"拿到手"之前就已经完成,校验代码根本没有获得执行机会。这就是"先加载、后检查"这类防线失效的原因——检查的时机晚于风险发生的时机。
更容易被低估的是可达代码的规模。恢复过程能触及的不只是项目自己定义的类型,还包括依赖树中所有可被引用的类与调用。自己的代码一行未改,换一批依赖或升一个版本,可被组合利用的路径就可能变化。风险面因此不完全由开发者写下的代码决定,也很难靠通读自己的源码来穷举。基于同样的理由,来源不明的 pickle 数据应当被视为不可加载,而不是"先看看里面有什么再决定"。
把反序列化当作执行边界
更稳妥的设计是把"恢复对象"与"读取数据"区分成两件事,并在加载前完成判断,而不是加载后补救。可以按以下几点核对:
- 这段数据是否由自己生成,且传输与存储环节都在可控范围内;
- 是否存在更弱的表达方式,即只承载数据、不重建对象;
- 输入的格式与长度是否在进入加载步骤之前就已受限;
- 执行加载的脚本是否同时具备读写本地文件与访问网络的能力,权限能否收紧。
如果自查中发现某个脚本正在恢复来源不明的对象,合理的顺序是先停止相关任务、保留日志与输入样本,再回头判断这段输入本来是否需要以对象形式传递。多数场景下答案是不需要,用受限的数据表达替换掉这一步,比在加载之后追加任何检查都更接近于真正移除风险。



参与讨论
权限最小化可能是最好防护
依赖库多了真不敢乱反序列化
那JSON算安全的吗?
一直以为只是解析数据,没想到这么危险
原来反序列化本质是执行代码