系统:运行中
← 返回所有攻击
INFRASTRUCTURE CRITICAL NEW

gRPC 上的 pickle:机器人策略服务器的未认证 RCE

Hugging Face 的 LeRobot 通过未认证的 gRPC 以 pickle 传输机器人到策略的推理数据——任何能够到达该端口的主机都可获得远程代码执行。2026 年 6 月的修复彻底移除了 pickle。

2026-07-15 // 5 min affects: lerobot, async-inference, robot-policy-servers

这是什么?

2026 年 6 月 29 日,SecureLayer7 研究团队发布了针对 LeRobot 的一个未认证远程代码执行漏洞分析。LeRobot 是 Hugging Face 的开源机器人框架。其异步推理管线将机器人策略拆分为客户端–服务器两部分:运行在物理机器人上的客户端将观测数据流式发送给部署在独立 GPU 主机上的 PolicyServer,后者再将动作流式返回。其传输层为 gRPC——而载荷是以原始 pickle 字节承载的。

该漏洞正是这一选择的必然后果。本文基于公开的安全公告与上游修复撰写,此处不复现任何可用的攻击代码。其教训关乎部署架构,而非模型本身:当一个服务组件用 pickle 反序列化不可信的网络数据,且信道毫无认证时,网络本身就是那个漏洞。

工作原理

Python 的 pickle 并非数据格式,而是一套小型的栈式字节码,其操作码会在加载过程中调用任意可调用对象。CPython 明确写道:“pickle 模块并不安全。只反序列化你信任的数据。” 任何对象都可以定义其在反序列化时的行为,因此一段精心构造的数据块可以在被反序列化的瞬间执行命令,早于任何后续校验。

在受影响的版本中,异步推理处理函数直接从链路上读取攻击者可控的字节,并将其交给 pickle.loads()

# 易受攻击的模式(示意)
policy_specs = pickle.loads(request.data)   # nosec  <-- 在校验之前执行

两个问题叠加。其一,反序列化发生在本应校验消息的类型检查之前,因此对象早已被构造出来——而构造正是危险行为发生之处。其二,gRPC 监听器以 add_insecure_port(...) 绑定:无 TLS、无令牌、无双向认证。默认拓扑假定机器人与策略服务器共处一个受信任网络(VPC 或 Tailscale 网格),但一旦端口(默认 TCP/50051)对任何不可信主体可达,该假设便彻底失效。此漏洞还是双向的:服务器同样对其动作响应进行序列化,因此一个恶意或已被攻陷的策略服务器可以将同一原语反向用于每一个接入的机器人客户端。

代码中反复出现一个信号:每个 pickle 调用旁都跟着 # nosec 注释——它压制了静态分析告警(Bandit 的 B301 规则),却未处理该告警所指出的运行时风险。

为何重要

受影响的代码随该框架一并分发,而这一框架用于训练和部署真实机器人策略,因此暴露面包括:共享的科研 GPU 集群、多机训练拓扑、长期挂着的演示 notebook,以及运维者从未意识到 gRPC 正在监听的云端部署。仅一个可达端口即可获得服务器进程权限下的代码执行——在参考容器中被报告为 root——而在 GPU 主机上,这距离模型工件、数据集与云凭据仅一步之遥。

这里有一处尖锐的讽刺:Hugging Face 正是为消除模型文件的”pickle 问题”而编写了 safetensors,其文档以粗体劝告不要加载来自不可信来源的 pickle 文件。同样的反模式却在技术栈的另一角落——推理传输层——再度出现,而这恰恰是反序列化漏洞在整个 AI 服务生态中持续潜伏之处。

防御措施

绝不对网络可控的数据调用 pickle.loads()。持久的修复方案是采用带类型、不可执行的线格式。上游补丁用 safetensors 承载张量、用 JSON 承载元数据,并包裹在一个携带类型标签的信封中,由反序列化器对照预期类型进行校验。这既移除了操作码解释器,又强制了模式,还能拒绝被路由到错误处理函数的消息。

对传输层进行认证。gRPC 并不等于认证——mTLS 或令牌认证需要主动启用。用凭据绑定服务端点,而非使用 add_insecure_port,并在机器人与策略服务器之间要求双向 TLS。

将网络视为敌对环境。默认拒绝流向推理端口的入站流量,监听 loopback 或私有接口,绝不将策略/推理端口暴露给任何不可信第三方可达的网络。将 GPU 主机与常规工作负载隔离分段。

以静态方式排查该模式。在面向网络的 Python 服务中检索作用于任何可追溯至请求输入之数据的 pickle.loads——并将紧邻的 # nosec 视为一处发现,而非一种解决。

最小权限与出站控制。将服务进程的云角色收敛至最小,并在策略服务器进程派生出意外子进程(shell、解释器)或建立本不应有的出站连接时告警。

状态

项目详情
参考CVE-2026-25874(见 cve.org 记录)
披露安全公告发布于 2026 年 6 月 29 日
受影响LeRobot 异步推理(PolicyServer / 机器人客户端),v0.4.3 及更早版本
根因对未认证的 gRPC 输入调用 pickle.loads(),且在类型校验之前完成反序列化
影响策略服务器上的认证前远程代码执行;双向(恶意服务器可反打客户端)
修复上游 PR #3048——移除 pickle,改用 safetensors + JSON 类型化模式;升级并启用传输认证 / 网络隔离

Sources