跳到主内容
快讯直播
AI智模界
教程

用 Anthropic 安全扫描给开源项目做体检

开源项目有个尴尬处境:代码是公开的,安全债也是公开的。人工逐行看几千行 diff 不现实,商业 SAST 工具又要走预算审批。Anthropic 放出了两条可自用的路径——Claude Code 内置的安全审查命令,以及开源的 security-review GitHub Action。把它们组合起来,能给仓库做一次覆盖"改动 + 依赖 + 模型文件"的体检,产出一份能直接排期的修复清单。

先说清"免费"的边界:这两个工具本身开源、可自由获取和自托管;模型调用是否产生费用取决于你的账号方案,以 Anthropic 官方计费页面为准。下面照抄即可跑通。

这篇能做出什么

走完整个流程,你会得到 4 份报告和 1 张优先级表:

1. reports/diff-review.md:当前分支相对主干的安全问题,每条带 文件:行号、证据片段、触发条件和严重级别

2. reports/repo-scan.md:全仓库模式扫描结果(危险反序列化、命令注入、硬编码密钥等)

3. reports/deps.md:依赖漏洞清单,按"能否被外部触发"重新排序

4. reports/models.md:模型权重文件的来源与加载方式核查表

5. 一张 P0–P3 修复优先级表,可直接贴进 issue 或 PR 描述

报告里每条长这样,是能直接动手的粒度:

```markdown

[P0] 不可信 pickle 反序列化

  • 位置: serving/loader.py:42
  • 证据: torch.load(path) # 未限制加载行为
  • 触发: 任何能替换 models/ 下 .pt 文件的角色
  • 影响: 加载即执行任意代码
  • 修复: torch.load(path, map_location="cpu", weights_only=True)

或迁移到 safetensors 格式

```

前置条件清单

动手前确认这几项:

  • Node.js 与 npm:Claude Code 通过 npm 分发,版本要求以官方文档当前版本为准
  • Anthropic 账号或 API Key:本地交互使用走登录流程即可;CI 场景需要一个 Key
  • 仓库的可写副本:扫描过程只读源码,但报告要写到本地目录
  • Git 历史完整:改动级审查需要能对比主干,浅克隆会失败
  • Python 项目:建议准备虚拟环境,装 pip-audit
  • 可选:osv-scanner、npm audit、modelscan 或 picklescan,作为 AI 扫描的交叉验证

分步骤

第一步:装好 Claude Code 并确认能跑

```bash

npm install -g @anthropic-ai/claude-code

claude --version

```

然后进入目标仓库并启动:

```bash

cd /path/to/your-repo

claude

```

首次运行会走登录授权。团队或 CI 场景改用环境变量:

```bash

export ANTHROPIC_API_KEY="sk-ant-..."

```

这个 Key 只放在本地 shell 或 CI secret 里,不要写进仓库任何文件。

第二步:改动级安全审查(看 diff)

先切到你要审的分支,工作区保持干净:

```bash

git fetch origin

git checkout -b security-check origin/your-branch

```

在 Claude Code 交互界面里,直接输入内置命令:

```text

/security-review

```

它会分析当前分支相对主干的改动,逐条列出安全问题、位置和修复建议。如果你的版本没有这个命令,用第三步的提示词模板替代即可,效果接近。

需要脚本化、把结果落盘时,用非交互模式:

```bash

mkdir -p reports

claude -p "审查当前分支相对 origin/main 的全部改动。按安全问题逐条输出:文件:行号、证据代码片段、触发条件、影响、修复方案、严重级别(P0-P3)。没有发现问题的类别也要明确说明。" \

> reports/diff-review.md

```

第三步:全仓库扫描(不只看 diff)

只审 diff 会漏掉历史遗留问题。准备一份固定的提示词文件,让每次扫描口径一致:

```markdown

<!-- security-scan-prompt.md -->

你是安全审计员,正在审查一个开源仓库。请按以下检查项逐一排查:

1. 反序列化:pickle.load / torch.load / joblib.load / yaml.load(未用 SafeLoader)等

2. 命令执行:os.system、subprocess 带 shell=True、eval、exec

3. 注入类:SQL 字符串拼接、模板注入、路径穿越(../ 拼进文件路径)

4. 网络类:SSRF(用户可控 URL 直接请求)、未校验的重定向

5. 密钥与凭据:硬编码的 token、密码、私钥、内网地址

6. 权限与配置:过宽的文件权限、关闭 TLS 校验、调试模式默认开启

7. 日志与错误:异常堆栈直接返回给客户端、日志里打印敏感字段

输出要求:

  • 每条包含 文件:行号、证据片段、触发条件、影响、修复方案
  • 严重级别用 P0/P1/P2/P3
  • 不确定的标注"待人工确认",不要猜测
  • 按严重级别从高到低排列

```

运行:

```bash

claude -p "$(cat security-scan-prompt.md)" > reports/repo-scan.md

```

仓库很大时可以按目录分批跑,一次喂一个子目录,结果合并。这样既避免上下文超限,也方便定位。

第四步:依赖体检

先让成熟工具把原始数据拉出来:

```bash

Python 依赖

pip install pip-audit

pip-audit -r requirements.txt -f json -o reports/pip-audit.json

Node 依赖

npm audit --json > reports/npm-audit.json

通用(按官方文档安装)

osv-scanner --lockfile=package-lock.json

```

然后把原始结果交给 Claude 做"可利用性"排序——原始报告经常几十上百条,直接看没法排期:

```bash

claude -p "读取 reports/pip-audit.json 与 requirements.txt。

按以下三条标准重新排序,不要照抄原来的顺序:

1) 这个包是否在生产路径上被真正调用

2) 漏洞是否可被外部输入触发

3) 是否存在已发布的修复版本

输出 P0-P3 清单,每条给出升级命令或临时缓解措施(如锁定输入、加校验、关闭该功能)。" \

> reports/deps.md

```

关键点:依赖漏洞不等于你的项目可被利用。一个只在开发脚本里用到的工具包报高危,和核心请求路径上的解析库报高危,处理顺序完全不同。

第五步:模型与权重文件体检

这一步是 AI 项目特有的,也是最容易出事的地方。先盘清家底:

```bash

find . -type f \( -name "*.pkl" -o -name "*.pt" -o -name "*.bin" \

-o -name "*.h5" -o -name "*.ckpt" -o -name "*.joblib" \) \

-not -path "./.git/*" -print

sha256sum models/* 2>/dev/null

```

再扫加载代码:

```bash

grep -rnE "torch\.load|pickle\.load|joblib\.load|yaml\.load\(|eval\(|exec\(|os\.system\(|shell=True" \

--include=*.py . | grep -v "\.git/"

```

把文件清单和命中结果一起交给 Claude 判断:

```bash

claude -p "以下是仓库中的模型文件清单和一处反序列化调用点。

请判断:(1) 每个格式的反序列化风险等级;(2) 哪些调用点缺少安全参数;

(3) 哪些可以迁移到 safetensors 或 ONNX;(4) 给出需要校验哈希的文件列表。" \

> reports/models.md

```

判断依据可以记住这几条通用原则:safetensors 和 ONNX 属于纯数据格式,加载时不执行代码;.pkl、.pt、.joblib、.ckpt 这类基于 pickle 的格式在加载阶段就可能执行任意代码,只应从可信发布方获取并校验哈希。第三方模型扫描器(如 modelscan、picklescan)可以作为交叉验证,能力范围以各自官方文档为准。

第六步:合成修复优先级

把四份报告丢给 Claude 合并,用统一的判定标准:

```bash

claude -p "综合 reports/ 目录下的四份报告,输出一张修复优先级表。

判定标准:

P0 = 可被未认证的外部人员触发,且导致代码执行或数据泄露

P1 = 需要认证或特定配置才能触发,影响核心功能

P2 = 需要本地权限,或影响面局限在开发环境

P3 = 加固类建议,无直接可利用路径

每条给:级别、问题、位置、修复动作、预估工作量。" \

> reports/priority.md

```

P0 和 P1 当天建 issue 并指派;P2 排进迭代;P3 攒成一次加固 PR 批量处理。

第七步:接进 CI(可选)

想让每个 PR 自动过一遍,可以用开源的 security-review GitHub Action。下面的结构供参考,with: 下的参数名以该仓库 README 为准:

```yaml

.github/workflows/security-review.yml

name: security-review

on:

pull_request:

types: [opened, synchronize, reopened]

permissions:

contents: read

pull-requests: write

jobs:

review:

runs-on: ubuntu-latest

steps:

  • uses: actions/checkout@v4

with:

fetch-depth: 0

  • uses: anthropics/claude-code-security-review@main

with:

claude-api-key: ${{ secrets.ANTHROPIC_API_KEY }}

```

新增仓库 secret 时,路径是 Settings → Secrets and variables → Actions。注意来自 fork 的 PR 拿不到 secret,需要在 workflow 里加条件跳过或改用其他触发方式。

最后把报告目录排除出版本控制:

```gitignore

reports/

```

常见坑与排错

只审 diff,漏掉历史问题。 内置审查命令盯的是改动。每季度单独跑一次全仓库扫描,把 repo-scan.md 和上一版做 diff,看新增了哪些风险点。

扫描产物里带密钥。 AI 会把命中的硬编码凭据原样写进报告。先用 git-secrets 或 GitHub 的 secret scanning 清理,再跑扫描;报告目录直接 gitignore。

结果全是泛泛而谈。 提示词里没说清输出格式时,容易得到"建议加强输入校验"这类废话。强制要求 文件:行号 加证据片段,颗粒度立刻下来。

一次喂整个仓库。 上下文超限后会开始丢文件。按目录分批,或者先写个脚本把每个文件截断到合理长度再喂。

假阳性太多导致没人看。 让人工复核后,在仓库里维护一份 security-ignore.md,写清"哪条、为什么不修、什么条件下重新评估"。有记录的忽略才是有效忽略。

依赖报告全标高危。 npm audit 和 pip-audit 的评级基于 CVSS,不等于你的实际暴露面。必须经过第四步的可利用性重排。

模型文件直接塞给模型分析。 权重动辄几个 GB,传不进去也没必要。只喂文件清单、哈希和加载代码。

CI 里权限给太宽。 Action 只需要读代码、写 PR 评论。contents: read 加 pull-requests: write 就够,不要开 write-all。

非交互模式跑不动。 claude -p 遇到需要执行的命令时可能被权限拦住。CI 场景按官方文档配置好允许的工具范围,参数名以官方文档为准。

下一步建议

跑通一次之后,把体检变成习惯:

1. PR 模板加自查项:在 .github/pull_request_template.md 里放一句"改动是否涉及反序列化、命令执行、文件路径拼接?"

2. 依赖扫描上定时任务:用 schedule 触发,每周跑一次依赖检查,新披露的漏洞能第一时间发现

3. 补一个 SECURITY.md:写清漏洞上报渠道和响应时限,开源项目收到安全报告时不会手忙脚乱

4. 加 pre-commit 钩子:用 detect-secrets 之类的工具在提交前拦住密钥

5. 生成 SBOM:把依赖清单固化成软件物料清单,出供应链事件时能快速回答"我用了没有"

6. 轮转历史凭据:扫描一旦发现硬编码密钥,改代码只是第一步,那把 Key 要立刻作废重发

体检的价值在"改完",不在"扫完"。先把 P0 清干净,再谈工具升级。

AI 生成本文由 AI 基于公开信息自动生成,仅供参考。