十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Hugging Face事件后的AI供应链安全审查与标准升级

Hugging Face事件后的AI供应链安全审查与标准升级 OpenAI 和 Hugging Face 在 AI 工程供应链里经常同时出现前者提供模型能力与 API后者是最大的模型和数据集分发平台。当 Hugging Face 平台发生安全事件后OpenAI 完成事件审查并升级安全标准这一动作本质上是所有使用第三方 AI 资产的企业都应该做一遍的供应链复盘。很多人以为安全审查就是“把模型删掉、换一个源”实际要看的是凭证、依赖、加载器、缓存、日志和回滚路径。这篇博客从工程视角拆解一次 Hugging Face 相关事件审查应该如何展开以及安全标准升级后使用者本地、CI 和生产环境分别应该落到什么配置上。外部能拿到的细节通常有限但不影响我们梳理审查方法。下面按“风险边界 - 证据采集 - 标准升级 - 操作清单 - 环境差异 - 排查链路 - 工程固化”的顺序把一次 Hugging Face 事件审查做成可以复用的技术方案。1. Hugging Face 事件审查先要看清供应链风险面1.1 Hugging Face 在 AI 工程链路中的角色Hugging Face 不只是模型下载站。它同时承担模型仓库、数据集仓库、Spaces 演示环境、Git LFS 文件托管和 huggingface_hub SDK 的分发入口。对于使用 Transformers、Diffusers、Datasets 的团队来说from_pretrained、load_dataset、hf download这些操作已经是日常的一部分。问题也出在这里。普通软件供应链里代码通过 Git 或包管理器分发AI 供应链里模型权重、分词器、配置文件、数据集脚本都会通过同一个平台分发。一个 Hugging Face 仓库被替换、一个 commit 被重写、一个下载链接被恶意复制影响范围会沿着“下载 - 缓存 - 加载 - 微调 - 推理”这条链路扩散。因此在审查这类事件时第一件事不是问“哪个文件有问题”而是先画一张资产图哪些服务器、哪些笔记本、哪些 CI 任务、哪些后台服务曾经从 Hugging Face 拉取过内容。资产图不完整后面的哈希校验和密钥轮换都会漏。1.2 模型权重、数据集脚本和缓存文件都可能成为风险载点不能把“模型文件”理解成一个单纯的二进制文件。模型文件的风险取决于加载方式。.safetensors设计目标就是避免反序列化任意对象它的加载流程更可控。.bin、.pt、.pth、.ckpt这类文件如果由 PyTorch 的torch.load直接加载可能在反序列化过程中触发 Python 对象构造逻辑也就是常说的 pickle 风险。更隐蔽的是一个仓库里除了权重文件还可能有数据集脚本、自定义模型代码、requirements.txt、Shell 脚本、Spaces 入口文件。只要加载器执行了其中的任意一行问题就不只是“文件被下载”了。下表整理了常见风险载点文件或入口类型常见场景主要风险审查方式.safetensorsTransformers 模型权重相对较低仍要校验哈希对比仓库 sha256.pt/.pth/.bin/.ckptPyTorch 权重、微调产物pickle 反序列化可能执行代码优先转 safetensors数据集脚本load_dataset加载脚本可执行任意代码关闭 trust_remote_code自定义 modeling 文件trust_remote_codeTrue远程代码直接运行vendor 到本地并审查镜像站或网盘分享绕过官方通道下载来源不可控无法溯源只允许内网固定镜像缓存目录HF 默认缓存旧文件残留绕过新策略清理或迁移到只读目录另一个容易被忽略的地方是缓存目录。Hugging Face Hub 在本地会保留~/.cache/huggingface/hub/之类的缓存同一个仓库名和 revision 在后续加载时可能不会重新下载。事件审查时如果只检查业务代码里的下载路径不检查缓存目录就会漏掉“文件虽然来自 Hugging Face但实际已经落在磁盘上并被加载”的情况。1.3 审查目标不是追责而是还原影响面一次安全事件审查的产出最终要回答几个问题哪些仓库、哪些 revision、哪些文件被下载过。这些文件在什么时间、被哪个进程加载执行过。加载之后有没有产生异常的网络请求、文件写入或命令执行。运行环境中是否存在 API key、数据库密码、云凭证等敏感信息。最后要给出处置措施清理文件、轮换密钥、升级加载策略、补审计日志。所以不要急着在受害机器上执行“删除所有模型文件”这种操作。删除之前要先保留证据。比较好的顺序是先隔离再复制日志和文件哈希最后再处置。这样后续还能核对影响范围。2. 审查链路资产清单、文件溯源、日志定位2.1 先建立资产清单再讨论漏洞审查的第一步是找到所有可能相关的模型文件和代码调用点。可以直接在服务器或代码仓库里执行查找命令。先找大文件判断哪些是权重文件find . -type f \( -name *.bin -o -name *.pt -o -name *.pth -o -name *.ckpt -o -name *.safetensors -o -name *.gguf \) -print0 | xargs -0 ls -lh | sort -k5 -h再找代码里触发 Hugging Face 下载和加载的地方grep -R from_pretrained\|load_dataset\|huggingface_hub\|snapshot_download --include*.py .对于已经上线运行的推理服务还需要检查进程和运行目录ps -ef | grep -E python|uvicorn|gunicorn | grep -v grep lsof -p pid | grep -E huggingface|model|tmp|cache这里的重点是建立一个“代码路径 - 文件路径 - 进程 ID”的对应关系。只找到文件不找到加载它的代码后面依然无法判断影响。2.2 用 Hugging Face 仓库元数据还原来源在本地文件之外还需要确认模型实际来自哪个 Hugging Face 仓库。可以使用huggingface_hub的 API 信息把仓库 ID、commit SHA、更新时间、是否私有记录下来。from huggingface_hub import HfApi api HfApi() repo_id your-org/your-model info api.model_info(repo_id) print(repo_id:, info.id) print(sha:, info.sha) print(private:, info.private) print(last_modified:, info.last_modified) files api.list_repo_files(repo_id) for filename in files: print(filename)不要用“在页面上看到的文件名”作为唯一凭据。Hugging Face 仓库内容是可变对象相同的 repo_id 在不同时间可能指向不同的 commit。事件审查时要把 commit SHA 记录下来而不是只记仓库名。如果以后需要复现审查可以固定到同一个 commit 上。2.3 从日志找执行痕迹和网络出口模型加载本身通常不会打印详细日志但异常行为会留下痕迹。优先检查以下几类系统或服务的标准输出是否出现torch.load、pickle相关提示。模型加载后是否有新的 TCP 连接。是否有进程在运行时读取了用户的 SSH 私钥、云凭证、shell history 或临时目录。是否有新增的计划任务、启动脚本或模型目录里的可执行文件。可以用下面命令缩小范围journalctl -u my-model-service --since 2025-01-01 00:00:00 | grep -iE torch.load|huggingface_hub|pickle|error也可以采样进程的网络连接lsof -p pid | grep -E TCP|UDP如果发现进程在加载模型后访问了与业务无关的域名要立刻记录目的 IP 和端口并把该进程的容器镜像或可执行文件保存下来不要直接删除。3. 升级后的安全标准应该落在哪些配置上3.1 不允许在每台机器直连 Hugging Face 下载升级安全标准后最核心的变化不是“多扫两次毒”而是改变下载拓扑。每台推理机、每台开发机、每个 CI 任务都直接访问 Hugging Face意味着平台侧一旦发生仓库替换或账号入侵影响面会成倍扩大。建议的做法是建立一层“内部可信源”在受管服务器或内部对象存储中下载一次模型。计算每个文件的 SHA-256。生成 MANIFEST 文件。业务机器只从内部可信源拉取并校验 MANIFEST。这种模式下Hugging Face 不再直接暴露给所有终端而只暴露给少数负责拉取和同步的机器。即使上游仓库被污染内部模型注册表仍然保留上一份已验证的产物。下载到本地并生成校验信息的命令可以这样组织hf download your-org/your-model --revision commit-sha --local-dir ./model-cache sha256sum ./model-cache/* ./model-cache/MANIFEST.sha2563.2 用哈希固定模型产物而不是使用 latest模型仓库不像代码仓库那样每次发布都打一个稳定 tag。很多团队习惯下载latest但latest是一个变化的目标。安全标准升级后应该把 repo_id、revision、文件哈希作为一组不可拆分的约束。下面是一份最小策略文件{ your-org/your-model: { model.safetensors: sha256:abc123... }, your-org/your-dataset: { data.parquet: sha256:def456... } }校验代码可以放在 Python 脚本里import hashlib import json from pathlib import Path def sha256_file(path: Path) - str: digest hashlib.sha256() with path.open(rb) as f: for chunk in iter(lambda: f.read(1024 * 1024), b): digest.update(chunk) return digest.hexdigest() manifest json.loads(Path(models.policy.json).read_text()) for repo_id, files in manifest.items(): for filename, expected in files.items(): expected_hash expected.removeprefix(sha256:).lower() actual_hash sha256_file(Path(models) / repo_id / filename) if actual_hash ! expected_hash: raise SystemExit( fhash mismatch: {repo_id}/{filename}, fexpected {expected_hash}, got {actual_hash} ) print(all verified)这里要注意一个常见错误只看文件大小。Hugging Face 上的文件可能是 Git LFS 指针也可能是大文件本身。下载后文件大小和 Web 页面显示不一致时要优先怀疑没有真正拉取到模型权重而不是直接忽略。3.3 加载模型时关掉不必要的远程代码和 pickle在代码层面有几条应该成为默认红线。第一条能使用.safetensors就不要使用torch.load加载.pt/.pth。代码出现torch.load(..., weights_onlyFalse)要进入人工审查。如果只是为了加载权重应该改为from safetensors.torch import load_file tensors load_file(models/your-org/your-model/model.safetensors)第二条Transformer 模型加载时默认关闭远程代码执行。典型的加载方式应该是from transformers import AutoModelForCausalLM, AutoTokenizer model_path ./models/your-org/your-model tokenizer AutoTokenizer.from_pretrained( model_path, local_files_onlyTrue, trust_remote_codeFalse, ) model AutoModelForCausalLM.from_pretrained( model_path, local_files_onlyTrue, trust_remote_codeFalse, use_safetensorsTrue, )local_files_onlyTrue会强制只读取本地目录不会继续访问网络trust_remote_codeFalse会阻止执行仓库里的自定义 modeling 文件。如果模型确实需要自定义代码才能加载正确做法是把自定义代码下载到本地经过代码审查后再放回模型目录而不是直接把trust_remote_code打开。第三条数据集加载同样要控制脚本执行。load_dataset在加载特定数据集时可能会运行数据集脚本推荐写法是from datasets import load_dataset ds load_dataset( your-org/your-dataset, revisioncommit-sha, trust_remote_codeFalse, )如果加载失败且提示需要远程代码要回到“审查脚本 - vendor - 本地加载”的流程不要盲目允许。3.4 API Key、镜像和共享目录更需要注意事件审查里最容易出错的一环是 API Key。模型文件被加载后恶意代码可能会读取环境变量、shell history、云厂商临时凭证和项目目录下的.env文件。凡是可能接触过受影响模型的个人 token、CI token、云端密钥都应该在事件处置窗口内轮换。轮换不是只改一个变量。应该把新密钥写入密钥管理服务让旧密钥立即失效再检查代码里是否还有硬编码。可以先用命令扫描仓库历史git log -p --all | grep -iE sk-[A-Za-z0-9]{20,} || true如果有条件使用 Gitleaks 等工具做全量扫描gitleaks detect --source . --report-format json --report-path leak-report.json对于网络受限团队常用的内网镜像或镜像站需要额外核对一件事镜像站是否记录了上游 repo_id 和 commit。如果镜像只是“转发下载链接”而不保存原始 commit 信息和文件哈希就无法判断镜像内容是否和上游一致。使用镜像站之后依然要在下游完成文件哈希校验不能认为“走了镜像就安全”。4. 在 Hugging Face 下载模型和数据集的可执行清单4.1 下载前先确认仓库、owner 和 revision下载前第一件事是确认仓库归属。Hugging Face 上存在同名或仿冒仓库的情况。企业团队在模型目录里看到qwen2.5-7b-instruct这类名字时先看 owner 是不是官方组织再看该仓库最近的 commit 和 star 数量。不能只看模型名。下载时尽量固定 commit SHA不使用main或latesthf download your-org/your-model --revision commit-sha --local-dir ./models/your-org/your-model这样会得到一个与某个 commit 对应的确定性目录。后续加载、测试、审计都以这个目录为准。4.2 数据集也要固定 revision数据集风险经常被低估。一个 CSV 或 JSON 文件本身不会执行代码但有些数据集的加载脚本会在处理数据时运行 Python。固定 revision 之后即使数据源更新本地加载的数据集也不会因为 repo 更新而变化。from datasets import load_dataset ds load_dataset( your-org/your-dataset, revisioncommit-sha, trust_remote_codeFalse, cache_dir./data/cache, ) print(ds)cache_dir建议显式设置到项目目录内不要依赖默认缓存。这样既方便释放磁盘也方便在出问题时清空。4.3 保存 MANIFEST 并纳入 CI 校验建议每个模型目录都保留一份MANIFEST.sha256内容类似abc123... your-org/your-model/model.safetensors def456... your-org/your-model/tokenizer.json在 CI 或部署脚本里统一校验cd ./models sha256sum -c MANIFEST.sha256如果校验失败流程立即终止。这一步能拦截大部分“文件被替换、下载中断、镜像内容不一致”的问题。4.4 加载前先跑最小验证用例模型进入推理服务之前先写一个最小加载脚本确认模型能从本地目录正常加载并产生预期的张量形状。from transformers import AutoTokenizer, AutoModelForCausalLM model_path ./models/your-org/your-model tokenizer AutoTokenizer.from_pretrained( model_path, local_files_onlyTrue, trust_remote_codeFalse, ) model AutoModelForCausalLM.from_pretrained( model_path, local_files_onlyTrue, trust_remote_codeFalse, use_safetensorsTrue, ) inputs tokenizer(hello, return_tensorspt) outputs model(**inputs) print(outputs.logits.shape)这个验证的目的不是跑 benchmark而是确认加载链路中没有访问外部网络、没有使用远程代码、没有触发反序列化任意对象。第一次在干净环境跑通后再把同样的加载参数复制到生产代码。5. 不同环境的执行力度应该不一样5.1 本地研究环境本地开发允许直接从 Hugging Face 下载但建议至少在第一次下载时固定 commit SHA并记录文件哈希。不要为了方便把trust_remote_codeTrue写进常用脚本。个人电脑通常连接着私人账号和 GitHub token恶意模型一旦执行暴露面比服务器更大。本地环境还应该避免“共享模型目录”模式。团队共用一台 GPU 机器时如果某个成员下载了一个可疑模型其他人再从这个共享目录加载相当于风险被二次传播。共享目录必须配合只读权限和文件哈希校验。5.2 测试和 CI 环境测试环境的主要风险是缓存不可控和依赖更新。CI 里如果每次跑测试都重新下载模型会浪费大量时间和带宽如果长期缓存旧模型又可能在 Hugging Face 仓库更新后继续使用旧文件。建议在 CI 中显式设置HF_HOME或HF_HUB_CACHE指向一个独立目录并定期清理。模型文件的来源、revision、hash 作为 CI 变量或配置文件的一部分随代码变更一起评审。5.3 生产推理环境生产环境标准要更严模型文件只从内部可信源获取推理机不直接访问 Hugging Face。模型目录挂载为只读服务进程没有写权限。推理服务进程使用独立低权限用户运行。默认禁止公网出网必须出网时需要明确 allowlist 并记录日志。密钥不放在环境变量里通过密钥管理服务注入。模型加载参数写死在代码配置中不允许运行时通过 HTTP 参数修改。生产环境还要考虑回滚。每次模型升级都保留上一份 MANIFEST 和模型文件归档当前版本异常时可以快速切换到上一版本而不是重新去 Hugging Face 下载。下表可以当作环境差异速查环境模型来源revision 固定哈希校验网络约束密钥管理本地开发允许官方 repo建议建议关注异常出网本机 profile 不提交CI/测试官方 repo 或内网缓存必须必须CI 记录下载请求CI Secret生产只允许内部可信源必须必须默认禁公网密钥管理服务6. 常见误区和快速排查链路6.1 误区杀毒软件没报毒就说明模型安全模型文件不是传统 PE 可执行文件杀毒软件很可能无法扫描 pickle 序列化数据里的代码执行逻辑。即使杀毒软件没有报毒仍然要按照“来源 - commit - hash - 加载器”的顺序验证。反过来杀毒软件报毒也不是最终结论还需要进一步判断是误报还是真实恶意行为。6.2 误区只固定 repo_id不固定 revisionHugging Face 仓库会持续更新repo_id 本身不是不可变引用。攻击者如果控制了某个仓库可以推送新的 commit 或修改文件内容。固定 commit SHA 才是可信操作。文件和 commit 的对应关系要由哈希保证。6.3 误区加载失败就打开 trust_remote_code模型加载失败的原因有很多依赖缺失、权重格式不一致、分支不同、缺少自定义 modeling 文件。直接打开trust_remote_code会把远程代码执行风险引入。正确做法是先看日志确认缺失的是哪个模块再把模块代码下载到本地审查。6.4 从异常现象到根因的排查顺序如果已经发生疑似问题按下面顺序排查确认是哪个进程或容器加载过模型先隔离不要删除现场。找到模型文件来源检查 Hugging Face 缓存目录和项目模型目录。使用 Hugging Face API 查看 repo_id 对应的 commit SHA 和文件列表。对比本地文件哈希与上游哈希。查看加载参数是否有torch.load、trust_remote_codeTrue、pickle。检查网络连接和进程日志判断是否产生异常外联。检查 API key、数据库密码、云凭证是否可能在运行环境中被读取。完成凭证轮换后再清理模型文件和缓存。复现审查过程把检查项固化为脚本或 CI 流程。如果怀疑恶意代码已经执行不要在受感染机器上继续执行高权限扫描先通过网络隔离或停服限制进一步扩散。7. 把这条标准固化到日常工程流程7.1 AI 供应链发布检查清单每次引入新模型、新数据集或升级模型版本建议过一遍清单是否记录了 repo_id、owner、commit SHA、文件哈希。是否使用.safetensors格式是否避免直接torch.load。是否设置local_files_onlyTrue是否关闭trust_remote_code。是否将模型文件同步到内网可信源终端环境是否允许直连 Hugging Face。是否生成 MANIFEST 并在 CI 或部署前校验。是否扫描了 Python 依赖和密钥泄漏。是否有审计日志记录模型加载时间、加载进程、文件路径。是否有明确的回滚方案和上一版本归档。这份清单最好放进 pull request 模板而不是只存在于安全文档里。7.2 在 Code Review 和 CI 里设置红线代码评审阶段要拦截风险写法。建议设置几条硬性红线禁止未经评审直接合并包含torch.load的代码。禁止生产代码中出现默认从 Hugging Face 在线下载模型的逻辑。禁止随意打开trust_remote_code。禁止在仓库中提交任何形式的 API Key 和密钥。禁止使用未固定 revision 的模型仓库。CI 阶段可以配合工具检查 Python 依赖和密钥pip-audit -r requirements.txt模型文件本身不一定能快速扫描但环境依赖可以扫描。依赖漏洞和模型来源问题是两条独立的安全线不能互相替代。如果团队使用 OpenAI Codex 这类 AI 编程工具同样需要把工具读取的仓库、使用的 token、可以执行的命令纳入审查范围。AI 编码工具不是安全的豁免区它一样可能读取到不安全的模型目录或误用凭证。7.3 从人工检查走向自动化模型注册表仅仅靠每个人在下载模型时手动执行sha256sum长期看一定会漏。下一步可以考虑搭建一个内部模型注册表模型文件只有通过审批和哈希校验后才能进入注册表推理服务从注册表拉取固定版本。模型元数据可以包含model nameowner organizationsource repo_idsource commit SHAfile hashes引入人审批人上架时间下架时间这套信息不仅用于安全审查也能解决模型重复下载、版本混乱、谁在用什么模型的问题。真正把“事件后升级的安全标准”变成日常工程规则靠的不是一次巡检而是把检查项嵌入到下载、加载、发布、运行的每个环节。Hugging Face 事件审查的关键结论并不复杂模型来源必须可信模型文件必须可验证模型加载必须可控模型使用必须可审计。围绕这四条线把仓库信息、commit、哈希、加载参数、日志和密钥管理全部串联起来才能在下一次事件到来时不再靠运气排查。
返回列表