LMCache CVE-2026-105192 深度分析:多进程 ZeroMQ 传输层的未认证 RCE——AI 推理基础设施的冷门攻击面
一、事件概览
2026 年 10 月 7 日,JFrog 安全研究团队披露了 LMCache 中的一个未认证代码执行漏洞,编号 CVE-2026-105192,CVSS 9.8(Critical)。攻击者无需任何凭证,只要能访问暴露的 LMCache 端口,就可以在宿主机上执行任意命令——在常见部署模式下,这个命令以 root 权限运行。
LMCache 是 vLLM 生态中广泛使用的 KV Cache 共享层,负责在大语言模型推理服务之间复用预计算好的注意力缓存,显著降低重复前缀(长系统提示、RAG 文档、多轮对话历史)的推理成本。它的典型位置决定了它一旦失守,后果不只是一个组件被拿下,而是整条推理管线的性能护城河变成攻击者的立足点。
最棘手的是:披露时没有可用修复版本,缓解手段只有网络隔离。
二、架构背景:LMCache 的多进程 ZeroMQ 传输
2.1 为什么用 ZeroMQ
LMCache 在一个推理节点上通常跑多个进程:vLLM 推理进程、缓存管理进程、以及跨节点同步进程。它们之间需要低延迟、高吞吐的消息传递。ZeroMQ(ZMQ)因其"无 Broker、低延迟、API 极简"的特性成为自然选择。
典型拓扑:
┌────────────────────────────────────────────────┐
│ GPU 节点 A │
│ ┌─────────┐ ZMQ (ipc/tcp) ┌────────────┐ │
│ │ vLLM #1 │ ◄──────────────► │ LMCache │ │
│ └─────────┘ │ Controller │ │
│ ┌─────────┐ │ (多进程) │ │
│ │ vLLM #2 │ ◄──────────────► │ │ │
│ └─────────┘ └─────┬──────┘ │
└──────────────────────────────────────┼─────────┘
ZMQ over TCP │
(跨节点同步) ▼
┌────────────┐
│ GPU 节点 B │
│ LMCache │
└────────────┘问题就出在 tcp:// 跨节点通道上。
2.2 漏洞根因:传输层把"消息"当"指令"
根据 JFrog 的分析,问题出在 LMCache 的 multiprocess ZeroMQ transport 实现:该传输层接收的 ZMQ 消息会被处理逻辑中某条路径直接交给本地执行(反序列化 + 派发,且派发目标包含可执行任意 Python 表达式的入口,等效 eval/exec 语义),而这条通道没有认证、没有消息来源校验、没有能力白名单。
用一句话概括:任何一个能连上该 ZMQ 端口的人,都在事实上获得了"在 LMCache 进程里跑代码"的权限。LMCache 在常见 Kubernetes/GPU 主机部署中以 root 运行(为了访问 GPU 设备和宿主挂载),所以 RCE 等于 root shell。
用代码示意漏洞模式(非真实源码,还原根因结构):
# 漏洞模式示意:ZMQ server 直接执行不可信消息
import zmq, pickle # pickle 反序列化本身就是 RCE 原语
context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind("tcp://0.0.0.0:8100") # 无认证绑定所有网卡
while True:
payload = socket.recv()
obj = pickle.loads(payload) # ← 攻击者发送恶意 pickle 即获得代码执行
socket.send(b"ok")即使实现不用 pickle,只要消息格式中存在被 eval、yaml.load(非 safe loader)、或动态 import 的字段,效果相同。传输层代码最常见的盲区是:作者默认"只有自己的进程会连上来",而忘记了 tcp:// 绑定的是物理网络。
三、攻击链复盘
1. 侦察:Shodan / Censys 上搜索暴露的 LMCache / vLLM 特征端口
│
2. 连接:攻击者直接 ZMQ connect 目标节点的 tcp:// 端口
│
3. 注入:构造符合消息格式的 payload,携带可执行表达式
│
4. 执行:LMCache 进程内 RCE(通常 root)
│
5. 横向:读取 GPU 节点上的模型权重、API Key、KV 数据;
以该节点为跳板扫描内网其他推理节点 / 数据库3.1 为什么说这是 AI 基础设施的系统性问题
这不是 LMCache 一家的问题。2026 年已披露的同类案例已经排成一条线:
| 漏洞 | 组件 | 根因 |
|---|---|---|
| CVE-2026-105192 | LMCache | ZMQ 传输未认证执行 |
| CVE-2026-51869 | DB-GPT v0.8.0 | 沙箱 API 静默回退 LocalRuntime,代码直接跑在宿主机 |
| CVE-2026-9198 | Langflow | 未认证 RCE |
| CVE-2026-72898 | Metabase | 未认证 SQL 注入 |
共同模式:AI 组件的"性能通道"(内部 RPC、管理端口、沙箱旁路)在设计时默认网络是可信的。这些通道往往不在安全审计清单上——团队会加固 HTTP API,却忘了 ZMQ、gRPC、Redis 协议通道。
四、检测与加固
4.1 立即可做的排查
# 1. 找出所有对外监听的 ZMQ 端口
ss -tlnp | grep -v 127.0.0.1
# 2. 确认 LMCache 进程绑定的地址与权限
ps aux | grep -i lmcache
ls -l /proc/$(pgrep -f lmcache | head -1)/fd | grep socket
# 3. 云上环境:检查安全组是否放开了推理节点的高位端口
# (AWS CLI 示例)
aws ec2 describe-security-groups \
--filters Name=group-name,Values=*gpu* \
--query 'SecurityGroups[].{id:GroupId,rules:IpPermissions[?ToPort!=null].[IpProtocol,FromPort,ToPort]}'4.2 防御清单(按优先级)
- 网络隔离是当前唯一可靠的缓解(披露时无修复版本)。LMCache 的跨节点 ZMQ 通道必须在私有网络内:
- K8s 部署:用 NetworkPolicy 限制只有同 namespace 的推理 Pod 可访问
yamlapiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: lmcache-allow-vllm-only namespace: llm-serving spec: podSelector: matchLabels: app: lmcache policyTypes: ["Ingress"] ingress: - from: - podSelector: matchLabels: app: vllm ports: - port: 8100 protocol: TCP - 禁止 0.0.0.0 绑定。单机场景一律用
ipc://(Unix domain socket)替代tcp://,文件系统权限天然提供一层控制。 - 升级关注:盯住 LMCache 官方 release,修复版本发布后第一时间升级;在此之前把该组件视为高危暴露面。
- 给所有 AI 组件做一次"非 HTTP 端口审计"。清单:ZMQ、gRPC、Ray(head 节点默认 8265 dashboard)、Redis、etcd、Jupyter。任何绑在 0.0.0.0 又无认证的都要处理。
- 降低进程权限。GPU 访问不需要 root——通过设备插件(K8s device plugin)或
--device传给非特权用户运行,把 RCE 的破坏上限从 root 压到受限用户。 - 监控 ZMQ 端口的外部连接。LMCache 正常运行时连接方是固定几台推理节点,出现新 IP 连接即为告警信号。
4.3 开发者层面:传输层代码的正确写法
如果自己维护类似的内部 RPC,记三条铁律:
- 默认不信网络:
tcp://绑定必须显式授权来源(CurveZMQ / mTLS / 至少 token 握手) - 禁用可执行反序列化:消息格式用 JSON/MessagePack + schema 校验,永远不要
pickle.loads网络数据 - 最小能力派发:消息处理器白名单化,不接受任何形式的动态代码
# 正确示范:带 token 握手 + 白名单派发的 ZMQ 服务
import zmq, json, hmac
SECRET = os.environb[b"LMCACHE_CHANNEL_SECRET"]
ALLOWED = {"cache_get", "cache_put", "stats"}
ctx = zmq.Context()
sock = ctx.socket(zmq.REP)
sock.bind("tcp://10.0.1.5:8100") # 只绑内网 IP,不绑 0.0.0.0
while True:
raw = sock.recv()
try:
msg = json.loads(raw) # JSON,杜绝 pickle
mac = hmac.new(SECRET, msg["body"].encode(),
"sha256").hexdigest()
assert hmac.compare_digest(mac, msg["mac"]) # 认证
body = json.loads(msg["body"])
assert body["op"] in ALLOWED # 白名单
result = handlers[body["op"]](body.get("args", {}))
sock.send(json.dumps({"ok": True, "data": result}).encode())
except Exception as e:
sock.send(json.dumps({"ok": False, "err": "rejected"}).encode())五、结语
CVE-2026-105192 的教训不是"LMCache 写了烂代码",而是整个 AI 基础设施层的默认网络信任模型该更新了。GPU 节点是 2026 年最值钱的服务器之一——上面有模型权重、有客户数据、有计费凭证。性能优化组件(KV Cache、分布式推理、向量检索)大量使用高性能无认证协议,这在天真的局域网假设下成立,在真实生产网络中就是一颗颗等着被点名的雷。
检查你的推理集群,先从 ss -tlnp 开始。
参考资料
- JFrog Security Research:LMCache CVE-2026-105192 披露(2026-10-07)
- Cybersecurity news weekly roundup October 12, 2026 — NetworkTigers
- LMCache 官方仓库:https://github.com/LMCache/LMCache
- ZeroMQ 安全指南:https://zeromq.org/labs/security/
- 关联漏洞:DB-GPT CVE-2026-51869、Langflow CVE-2026-9198

