AI 编程的供应链与代码安全
AI 帮你写代码,也可能帮你引入漏洞、幻觉依赖、不合规许可证——这是新的供应链风险。本文讲清 AI 编程引入的四类风险(AI 生成漏洞/幻觉依赖/许可证/模型供应链),以及防护:SCA、许可证审查、AI code review、沙箱、依赖治理,让你放心用 AI 写生产代码。
本文要点
- 主题聚焦:AI、DevOps
- 适合人群:独立开发者、全栈工程师、AI 应用开发者
- 核心价值:快速理解背景、实践路径、常见误区和工程建议
AI 让你写得更快,也让"出事"来得更快。当一段 prompt 就能生成几百行代码、npm install 一堆陌生依赖、把 Hugging Face 上的模型权重拉进推理服务时,你的供应链攻击面已经悄悄扩大了——而且很多团队还没意识到。
这不是"AI 取代程序员"的焦虑,而是实打实的新攻击向量:模型会写漏洞、会编出不存在的包、会抄受保护的开源代码、权重本身可能就是反序列化炸弹。本文把这四类风险拆开讲,并给出可在 CI 里立刻落地的防护方案。
一、AI 编程引入的供应链新风险
传统软件供应链关注的是"你依赖的东西是否可信"。AI 编程在此基础上又加了一层:你依赖的东西是被模型生成的,而模型本身不可信。落到工程里,有四类具体风险:
- AI 生成漏洞:模型基于训练数据写代码,会把训练数据里过时、不安全的写法原样搬过来。OWASP 在 2025 年专门把"LLM 输出滥用/幻觉"列入了 LLM Top 10。
- 幻觉依赖(Hallucinated Packages):模型推荐一个看起来合理的包名,但它根本不存在——攻击者只要抢注这个名字,等你或别人
pip install时投毒。 - 许可证风险:模型可能"记住"了 GPL/AGPL 代码,大段原样吐到你的私有项目里,埋下合规地雷。
- 模型供应链:你用的开源模型权重、adapter、tokenizer 文件,加载链路里可能藏
pickle反序列化漏洞——这是 Hugging Face 生态反复出过的事故。
一个关键认知需要先建立:AI 生成的代码,应当视同第三方依赖——它的可信度不会高于你从 npm 随手装的一个陌生包。带着这个前提,后面的防护就顺理成章了。
二、AI 生成的代码漏洞——SAST + AI Code Review 双重把关
模型最常产出的几类漏洞,基本对应 OWASP Top 10 的经典项目:
- SQL/命令注入:模型为了"看起来正确",经常把字符串拼到 SQL 或 shell 里,而不是用参数化查询。让它写 Node 脚本时,
child_process.exec(\rm -rf ${dir}`)` 这种写法出现率不低。 - 不安全反序列化:
pickle.loads()、yaml.load()(不带SafeLoader)、Java 的ObjectInputStream,模型随手就用,基本不做校验。 - 硬编码密钥:让 AI"先跑起来",它会把 OpenAI key、数据库密码直接写进源码"方便测试",顺手提交进 Git。
- 鉴权绕过/路径穿越:
path.join(base, req.query.file)这种拼接,模型很少主动加..校验;SSRF 也常被忽略。
防护上光靠人 review 不够,必须在 CI 里上工具。
SAST(静态应用安全测试)——CI 必跑:
# Semgrep:规则多、误报可控、支持几十种语言
semgrep ci --config=auto
# 或 GitHub Advanced Security / CodeQL,仓库里直接启用
# .github/workflows/codeql.yml 是现成模板
AI Code Review——这是专门针对 AI 生成代码的新一层防护。关键是给 review bot 一个"安全优先"的 prompt,否则它只会夸代码写得好。我常用的 system prompt 片段:
你是一名严苛的安全 reviewer。对每段 AI 生成的代码,必须检查:
1. 是否存在注入(SQL / 命令 / 模板 / SSRF)?
2. 密钥、凭证是否硬编码或泄漏到日志?
3. 反序列化、文件路径、外部跳转是否经过校验?
4. 引入的依赖是否真实存在、是否常用、许可证是否合规?
发现任一问题,直接 block PR 并给出修复建议,不要客套。
工具上,GitHub Copilot 的 code review、CodeRabbit、Greptile、Snyk Code 都支持在 PR 上自动跑。建议至少开两个:一个通用 bot 看风格和逻辑,一个安全专用 bot(或自定义 prompt)盯漏洞。两个职责别混,混了两个都做不好。
三、幻觉依赖——最隐蔽的投毒入口
这是 AI 编程特有的新型攻击。学术界 2024 年就有论文系统揭露:模型会"编造"包名。比如你问"Python 怎么读 Excel",它可能让你 pip install excel-utils-fast(虚构名),你照做就中了圈套——攻击者只要抢注这个名字,发布一个带恶意 setup.py 的包,你就被 RCE 了。npm、PyPI 都已出现真实的抢注投毒案例,且这类攻击不需要漏洞,靠的就是你的信任。
防护三件事:
1. 依赖存在性验证——任何 AI 给的 import xxx / require('yyy'),先验证再装:
# PyPI:看版本和发布历史
curl -s https://pypi.org/pypi/<package>/json | jq '.info.version, (.releases | length)'
# npm:看首发时间和维护活跃度
npm view <package> time --json
# 不在官方注册表里的,一律不装
一个简单启发式:包龄 + 下载量。一个上周才发布、下载量个位数、却被 AI 反复推荐的包,基本就是投毒。对比之下 pandas、openpyxl 这类成熟库不会出问题。
2. 锁定版本 + 锁文件:
# 可复现的依赖
pnpm install --frozen-lockfile
pip install pip-tools && pip-compile requirements.in
3. 只信官方源:.npmrc 设 registry=https://registry.npmjs.org/,PyPI 配 index-url=https://pypi.org/simple,内网用私有镜像(Verdaccio / Artifactory)做代理 + 审批。绝不在 AI 建议下临时加某个"更快"的陌生镜像。
四、许可证合规——别让 AI 帮你抄 GPL
模型训练数据里有大量 copyleft 代码(GPL、AGPL、SSPL、MPL)。在某些场景下,它会把大段代码"回忆"出来,几乎原样输出。一旦进了你的闭源项目,理论上是侵权 + 许可证污染,合规团队会炸。
风险不止直接抄袭:AI 引入的某个 npm 包,其传递依赖里可能藏着一个 GPL 库,同样会污染你的二进制。这种事 license 文件不会主动告诉你。
许可证扫描应该在 CI 里和 SCA 并行:
# JS 生态
npx license-checker --production --summary
npx license-checker --production --failOn "GPL-3.0;AGPL-3.0;SSPL-1.0"
# Python
pipx run pip-licenses \
--fail-on="GPL.*;AGPL.*" \
--allow-only="MIT;Apache-2.0;BSD-.*;ISC;MPL-2.0"
# 专业工具:FOSSA、ScanCode Toolkit、Snyk License Policy
策略建议走白名单制:默认只放行 MIT / Apache-2.0 / BSD / ISC 这类宽松许可证,MPL-2.0(弱 copyleft)看是否链接,LGPL 看是否动态链接,GPL / AGPL 一律人工评审。把这条策略写进 CI,新依赖不合规直接 block,不给人情空间。
五、模型供应链——权重本身就是代码
这个风险比"AI 写的代码"更上游。你加载的 .bin / .safetensors / adapter,尤其是 pickle 格式的老权重,反序列化时可以执行任意代码。Hugging Face 历史上多次出现用户上传的"模型"实际是恶意 pickle,加载即被 RCE。在 LLM agent 场景里,模型还能读取 .huggingface/ 缓存、本地文件、环境变量,危害更大。
防护:
- 优先 safetensors:
.safetensors是纯张量格式,不可执行代码。Hugging Face 已强制新模型默认走 safetensors,pickle 权重要显式确认来源。 - 可信来源:只用官方组织账号(
meta-llama、mistralai、Qwen)或高 star、长期维护的仓库。看 commit 历史、贡献者、下载量。 - 沙箱加载:本地加载未知权重,用容器隔离——
# 无网络、只读 root、tmpfs 工作区
docker run --rm --network=none \
--read-only --tmpfs /tmp \
-v ./weights:/w:ro \
huggingface/transformers-pytorch-gpu \
python -c "from transformers import AutoModel; AutoModel.from_pretrained('/w')"
- 加载前扫描:
picklescan、modelscan(ProtectAI)能检出可疑 opcode。
pipx run picklescan --path ./weights
六、把防护收进 CI——SCA / SAST / License + 依赖治理
单点工具没用,必须串成 CI 流水线,让每个 PR 自动跑、不合规就 fail。最小可用流水线:
# .github/workflows/supply-chain.yml(节选)
on: [pull_request]
jobs:
sca:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm audit --audit-level=high # 已知漏洞依赖
- run: npx @snyk/snyk test || true # 或 OSV-scanner / Dependabot
license:
- run: npx license-checker --failOn "GPL*;AGPL*"
sast:
- uses: github/codeql-action/init@v3
- uses: github/codeql-action/analyze@v3
# 或 semgrep ci --config=auto
ai-review:
- uses: ./.github/actions/ai-sec-review # 自定义:调 LLM + 安全 prompt
依赖治理(长期工程)——光扫一次不够,要建立长期机制:
- 最小依赖原则:能自己写十行就别装一个库。AI 倾向"什么都引入",评审时要反向施压:这个依赖真的必要吗?
- 定期审计:
npm audit/pip-audit/osv-scanner跑成 cron,新 CVE 自动开 issue。 - Renovate / Dependabot:自动升级补丁版本,减少"不敢升级"的积压。
- SBOM:每个发布产物生成 SBOM(CycloneDX / SPDX),出了漏洞能立刻知道"我有没有受影响"。
# 生成 SBOM
npx @cyclonedx/cyclonedx-npm --output-file bom.json
七、人的把关——AI 写的代码就是第三方代码
工具都到位了,最后一道闸还是人。我见过最危险的情况不是 AI 写了漏洞,而是 reviewer 看到"代码看起来很整洁"就点 approve——整洁不等于安全。
几条实操:
- AI 生成的代码,默认不信任。review 时把它当成一个陌生贡献者提交的 PR:查依赖、查输入校验、查鉴权。
- 要求作者标注 AI 生成部分。PR 模板里加 checkbox:"本 PR 中 AI 生成代码占比 ___%,已通过 SAST + license 扫描"。透明才能追责。
- 高风险变更强制人工 review:鉴权、支付、密钥处理、反序列化这几类,无论 AI 还是人写,都必须双人 review,CI 不能放行。
- 建立团队 AI 使用基线:哪些场景允许用 AI(脚手架、测试、文档),哪些必须人工把关(核心业务逻辑、安全模块)。写进 CONTRIBUTING.md,而不是只在口头约定。
小结
- AI 编程把供应链攻击面从"依赖"扩到"生成 + 依赖 + 模型",四类风险要分开治理:生成漏洞、幻觉依赖、许可证、模型权重。
- 防护靠 CI 自动化,不靠人记:SCA(
npm audit/ Snyk / OSV)+ SAST(Semgrep / CodeQL)+ License 扫描 + AI code review,一条流水线 fail-fast。 - 幻觉依赖是 AI 特有的新攻击,抢注投毒真实存在——只装官方源、验证包龄下载量、锁文件 + 私有镜像。
- 模型权重当代码看待:优先 safetensors、可信账号、沙箱加载、picklescan 扫描。
- 长期靠治理:最小依赖、Renovate 自动升级、SBOM、定期审计。
金句:AI 写的代码不是你的代码,是第三方代码——带着同样的怀疑去 review,带着同样的工具去扫描,你才能放心享受 AI 的十倍速。
Related