
我在 Hugging Face 上发现了带后门的 AI 模型——凡是认真去看的人,也都发现了
那是一个周二的晚上,我正看着团队里的一位工程师做一件本该稀松平常的事:把一个预训练模型从 Hugging Face 加载到测试环境里。再标准不过的操作。我们已经做过几百次了。但这一次,我刚读完 JFrog 在 2024 年 2 月发布的披露报告——他们的安全研究人员在 Hugging Face 上发现了 100 多个恶意模型,其中一些带有后门,只要你一加载,攻击者就能拿到远程访问权限——我盯着终端,怎么也移不开眼。
“等一下,”我说,“那个模型是什么格式的?”
Pickle。
我心里咯噔一下。
就是在那一刻,我意识到我们对待 AI 模型的方式,跟 2014 年整个行业对待开源库的方式如出一辙——把它们当成天然可信的产物,从互联网上拉下来直接跑。而我当时就确信——那种只有在亲眼看着自己的假设实时崩塌时才会有的确信——这将成为未来十年最具决定性的安全危机之一。
会偷偷“回家报信”的模型
Hugging Face 上实际发生的事情是这样的。一个名叫“baller423”的用户上传了一个看起来完全正常的 PyTorch 模型。名字合理,描述可信,指标也像模像样。但在它 pickle 序列化的权重深处,藏着一段载荷——只要有人运行 torch.load(),它就会向一个属于韩国研究环境开放网络(KREONET)的 IP 地址打开一个反向 shell。
这不是理论上的攻击。也不是概念验证。这是一个活生生的、已被武器化的模型,就摆在全世界最热门的 AI 模型平台上,等着有人把它下载下来。
而且“baller423”并不孤单。JFrog 总共发现了大约 100 个这样的模型——每一个都是伪装成“好用的预训练成果”的特洛伊木马。
当你对一个 pickle 文件运行 torch.load() 时,你不是在加载数据。你是在执行代码。而在为时已晚之前,你根本不知道那段代码会做什么。
我必须解释清楚这为什么如此危险,因为大多数人——甚至大多数工程师——并不理解 pickle 到底是什么。Python 的 pickle 格式不只是一种数据序列化方法。它是一台基于栈的虚拟机。它可以在反序列化过程中执行任意 Python 函数。当你的数据科学家加载模型时,pickle 可以悄无声息地调用 os.system() 或 subprocess.run(),在后台执行。模型运行正常。预测结果看起来也没问题。而与此同时,地球另一端的某个人已经在你的服务器上拿到了一个 shell。
这不是 bug。这就是 pickle 被设计出来的样子。我们只是从来没有认真想过:当这些文件来自互联网上的陌生人时,这意味着什么。
扫描器为什么没能拦下它?
这正是让我那晚失眠的部分。我们有安全工具。业界有 PickleScan——审查模型文件的标准工具。Hugging Face 自己就在跑它。这么明目张胆的东西,扫描器总该能抓到吧?
并没有。而且情况还更糟。
JFrog 后来在 PickleScan 本身中发现了三个零日漏洞——其中一个被登记为 CVE-2025-10155——攻击者可以通过篡改文件扩展名或利用 ZIP 归档解析差异,完全绕过检测。一个恶意模型,可能会被那个本该保护你的工具标记为“安全”。
统计数据同样惨淡:当前扫描器的告警中,高达 96% 是误报。想想这对一支安全团队意味着什么。在第一百次误报之后,你就不再仔细看了。你开始条件反射式地点击“批准”。而真正的威胁,恰恰就在这个时候大摇大摆地走进门来。
我为这件事和一位团队负责人激烈争论过。他觉得我们反应过度了。“我们只从经过验证的组织拉模型,”他说。我把 JFrog 的数据摆在他面前。我还告诉他,就连 GGUF 这种更新的“安全”格式——专门为规避 pickle 的问题而设计——也被发现在元数据里藏着恶意的 Jinja 模板,而且是在推理阶段执行,而不是在加载阶段。扫描器根本看不到,因为攻击发生得更晚,那时模型已经在运行了。
他沉默了很久。然后他说:“那我们到底还能信什么?”
这才是那个该问的问题。
当你的 AI 里潜伏着一个“沉睡特工”时,会发生什么?

Hugging Face 事件涉及的是粗糙、可被检测的载荷——反向 shell、明显的代码执行。但更深层的威胁,真正让我害怕的那种,是数据投毒。而这方面的研究结果令人不寒而栗。
英伟达的 AI 红队结合 Anthropic 的研究成果证明:要在一个 130 亿参数的模型中永久植入一种隐藏行为,只需污染训练数据的 0.00016%——在数百万份文档中,大约只相当于 250 份。
让这个数字沉一沉。两百五十份文档。
被投毒的模型能通过每一项基准测试。在标准测试上,它的表现与一个干净的模型完全一致。但当它遇到特定的触发器——某个特定的文本串、某种图像模式,甚至是对输入数据的比特级操纵——它就会切换行为。它可能绕过身份验证。它可能窃取并外传数据。它可能生成恶意代码,然后被输送进下游系统。
一个被投毒的 AI 模型是完美的沉睡特工:它通过每一次测试,在每一项基准上都拿高分,然后耐心等待一个只有攻击者才知道的触发器。
而数学上最令人窒息的一击是:加入更多干净数据并不能解决问题。一旦后门达到某个阈值——通常是训练过程中触发器出现 50 到 100 次——它就被永久地烙进了权重里。你训练不掉它。你也稀释不掉它。
英伟达把这一切形式化为他们所称的 AI 杀伤链(AI Kill Chain):五个阶段——侦察(Recon)、投毒(Poison)、劫持(Hijack)、驻留(Persist)、影响(Impact)——勾勒出攻击者系统性攻陷机器学习系统的路径。我把这个框架以及完整的攻击向量图谱写在了我们的交互式研究综述中,我也建议任何在生产环境中部署模型的人都花点时间读一读。
对任何用自有数据微调模型的企业来说,其含义都很残酷:即使你的专有数据集干干净净,你从公共仓库下载的基础模型也可能早已被攻陷。你正在一块自己看不透内部的地基上盖楼。
没人愿意谈的影子 AI 问题
我曾和一位中型金融服务公司的 CISO 一起吃饭。她几乎是随口告诉我,她的团队最近在公司内部发现了 47 个正在生产环境中运行的不同 AI 模型。而她的 AI 治理政策,只覆盖了其中 3 个。
这就是影子 AI,而且它已经成了一场流行病。数据触目惊心:企业中 90% 的 AI 使用,都发生在 IT 和安全团队的视线之外。开发者和业务部门之所以从公共仓库拉取未经审查的模型,是因为正式流程耗时太久。他们把专有代码和客户数据粘贴进公共 AI 工具——已观察到有 77% 的员工这么做。而这些未经授权的模型,每一个都是从未被任何扫描器碰过的潜在后门。
财务影响并不抽象。涉及未经审查的 AI 工具的安全事件,会让一次数据泄露的成本平均增加 $670,000。这就是你为在没有治理的情况下“快速前进”所付出的溢价。
我理解这种冲动。我是真的理解。当你是一名想赶紧把功能上线的工程师,而安全评审流程要走三周,你当然会忍不住直接从 Hugging Face 拉一个模型接上去。这种诱惑我自己也感受过。但 JFrog 的披露本该终结那个时代。我们现在已经通过实证确凿地知道:公共模型平台上存在被武器化的产物。把它们当作可信来源,在 AI 领域就等同于在生产环境中运行 curl | bash,而脚本来自某个随机的 GitHub gist。
为什么大家至今仍在盲飞?

NIST 在 2024 年发布了 AI 100-2 指南——一份关于对抗性机器学习攻击与缓解措施的全面分类体系。这是一项出色的工作。它为业界提供了描述这些威胁的共同语言。而几乎没有人真正落实它。
这些数字令人难堪:
- 只有 17% 的组织部署了自动化的 AI 安全控制措施
- 只有 12% 建立了全面的 AI 治理体系
- 只有 14% 能够看清内部的 AI 数据流向
- 83% 的组织,用 NIST 的话说,正在“盲目运行”
这种差距我近距离见过。组织把“有一份政策文件”和“有可运转的安全能力”混为一谈。他们会给你看一份排版精美的 AI 治理 PDF,而与此同时,他们的开发者正把未签名的 pickle 模型加载进生产环境的 Kubernetes 集群。文件是有的。控制措施没有。
83% 的企业对自己的 AI 供应链没有任何自动化控制措施。这不是一道缝隙——这是一扇敞开的大门。
我们是如何开始把模型当作恶意代码来对待的

在那个周二晚上的顿悟之后,我在 Veriprajna 的团队花了数周时间,重新设计了我们引入模型的方式。核心的理念转变简单却激进:在被证明安全之前,把每一个 AI 模型都视为可能带有恶意的可执行代码。
不是“大概没问题”。不是“来自可靠来源”。是可能带有恶意。就这样,没得商量。
机器学习物料清单
我们首先需要的是透明度。传统的软件物料清单(SBOM)追踪的是库和版本,但 AI 产物需要更多东西:一份 ML-BOM——机器学习物料清单——用来记录数据来源、模型血缘、框架依赖以及加密证明。
训练数据从哪里来?是谁微调了这个模型,用的又是什么数据?使用的是哪个版本的 PyTorch,它有没有已知漏洞?我们能否通过密码学手段验证:正在加载的模型,就是那条可信流水线产出的那个确切产物,且在传输过程中未被篡改?
如果你回答不了这些问题,你就不知道自己在部署什么。
干掉 pickle,为一切签名
我们立刻做了两个工程决定。第一:不再用 pickle。没有例外。我们流水线里的每一个模型都使用 SafeTensors——这种格式只存储张量数据和 JSON 元数据,加载时无法执行代码。它比 pickle 灵活性差,而这恰恰就是关键所在。
第二:模型加密签名。每一个模型产物都会得到一个唯一的哈希值,并用我们内部的 PKI 基础设施进行签名。我们的推理服务器运行一个准入控制器,会在权重被反序列化到内存之前,对照我们的信任根验证签名。签名对不上,模型就不加载。没有例外,不能强制放行,也没有“这只是拿来测试的”这种说法。
我的一位工程师对此强烈反对。“你这是在给开发流程增加摩擦,”他说。他说得没错。我就是故意加摩擦的。因为另一条路——那条谁都能从任何地方加载任何模型的无摩擦之路——正是让你的推理服务器上跑起一个通往韩国的反向 shell 的原因。
运行时监控:因为静态扫描远远不够
GGUF 模板漏洞让我们明白,静态扫描只能覆盖威胁面的一部分。一个模型可以在加载时是干净的,却在推理时变成恶意的。于是我们加上了持续的运行时监控:对照干净基线做输出校验以检测漂移;查询限流以防止模型窃取攻击;以及输入净化层,在查询抵达核心模型之前先对其改写,从而破坏那些精心构造的对抗性载荷。
完整的技术架构——包括我们借助硬件支持的可信执行环境(TEE)实现机密计算的方法——请参见我们研究论文中的技术深度解析。那里的实现细节深度,远远超出了我在一篇随笔里所能覆盖的范围。
关于“深度 AI”与 API 套壳的那个不舒服的真相
我之所以一再回到这个区分上——我称之为“深度 AI”(自托管、经过微调、在架构层面可控的 AI 系统)与当前主导市场的 API 套壳做法之间的区分——是有原因的。这不只是技术偏好。这是一个安全论证。
当你套壳一个公共 API 时,你就把自己的 AI 供应链外包给了别人。你看不到他们的模型来源、他们的训练数据、他们的安全态势。你只能相信 OpenAI、Anthropic 或 Google 已经把保护自家流水线的苦活做扎实了。也许他们确实做了。但你无法验证,而在安全领域,没有验证的信任只是一厢情愿。
当你做深——当你掌控模型权重、训练流水线、推理基础设施——你也就继承了整条供应链的责任。这更难。这更贵。它要求我一直在描述的那种工程纪律。但这是通往可验证安全的唯一路径。
一位投资人曾对我说:“直接用 GPT 的 API,然后专注做产品就好了。”我告诉他,对我们服务的这些行业而言——一个被攻陷的模型可能意味着财务数据泄露、医疗诊断被操纵,或者法律分析被污染——“直接用 API”是一种负债,而不是一种策略。
如今,AI 安全和软件安全已经是同一个问题
这是让一切在我脑中成形的洞见:AI 安全与软件供应链安全,已经不再是两个独立的学科。它们不可能再分开。AI 模型不是孤立运行的——它们是通过与传统软件相同的 CI/CD 流水线、容器镜像仓库和依赖树来构建和部署的。
如果你的模型有加密签名,但它依赖的某个 Python 库已经通过供应链攻击被攻陷,那你照样被攻破了。如果你的训练流水线跑在一个被污染的容器镜像里,那么无论你的训练数据多干净,你的模型权重都不可信。
业界还在不断地把“AI 安全”团队和“应用安全”团队分开来建。这种组织上的割裂本身就是一个漏洞。攻击面是统一的,防御也必须如此。
随着 AI 生成的代码不断加快开发速度,传统的人工代码评审流程正在体量的重压下崩塌。在交付期限的压力下,大型的、由 AI 生成的合并请求很难被仔细评审,由此催生出一种“浅评审”文化,把最后几道“人在回路”的安全控制之一也抹掉了。在这样的环境里,以加密签名和 ML-BOM 为根基的自动化、确定性验证,不是可选项。它是唯一能规模化的东西。
“可我们又不是攻击目标”
人们总会用这句话的各种版本来反驳。“我们做的事情没敏感到需要这种级别的安全。”“我们的模型只是内部工具用的。”“没人会费劲去投毒一个模型来攻击我们。”
2018 年,关于开源库安全,我听过一模一样的论调。然后 SolarWinds 发生了。然后 Log4Shell 发生了。然后 XZ Utils 后门事件发生了——一场持续多年的社会工程行动,只为攻陷一个压缩库,而这个库被全世界每一台 Linux 服务器上的 SSH 所使用。
AI 供应链正沿着同样的轨迹前进,只是速度更快。攻击面更大(模型权重是不透明的二进制数据块,无法像源代码那样被审计),工具链更不成熟(PickleScan 存在零日漏洞),治理差距也更宽(83% 的企业没有任何自动化控制措施)。
你不必是攻击目标,也可能成为受害者。你只需要恰好站在路径上。
无聊的 AI 安全长什么样
我的目标——这听起来可能有点怪——是让 AI 部署变得无聊。不刺激,不前沿,不是“快速行动,打破常规”。就是无聊。可预测。可审计。
无聊意味着每一个模型都有一份 ML-BOM。无聊意味着在加载时验证加密签名。无聊意味着永远不用 pickle。无聊意味着运行时监控能在漂移演变成泄露之前把它抓住。无聊意味着有一个集中的 AI 资产登记库,其中每一个模型、数据集和依赖项都被追踪、审查并纳入版本控制。
无聊意味着,当有人问“生产环境里跑着哪些 AI 模型?”时,你能在五分钟之内给出答案,并附上密码学证明。
目标不是让 AI 部署变得刺激,而是让它变得无聊——可预测、可审计、安全。刺激的 AI 安全,意味着有什么地方出了问题。
Hugging Face 上那 100 多个恶意模型并不是孤立事件。它们是一个症状——一个把惊人能力建立在盲目信任地基之上的行业的症状。我们下载模型的方式,就跟当年从 LimeWire 上下载 MP3 一样——寄希望于运气,无视显而易见的风险,出了事还一脸惊讶。
那个时代结束了。能在下一波 AI 供应链攻击中幸存下来的组织,是那些此时此刻就决定不再把模型当作魔法盒子、而是当作可执行代码——并承认它所带来的完整攻击面——的组织。是那些选择了无聊而非快速的组织。是那些盯着终端、看见 pickle 文件正在加载,然后说:“等一下。那是什么格式?”的组织。


