sast-skills 是做什么的?
将你的 LLM 编码助手转变为一个功能完备的 SAST 扫描器。为 Claude Code、Codex、Opencode、Cursor 以及任何加载 CLAUDE.md / AGENTS.md 技能文件夹的助手提供即插即用的 Agent 技能。
推荐使用 Claude Code 配合 Opus 以获得更好的质量;任何有能力的模型都能工作。
亮点
- 31 个技能覆盖 28 个漏洞类别 — 注入、损坏的访问控制、弱加密、文件处理、供应链、业务逻辑以及 LLM 特有的风险(提示注入、不安全的输出处理)。
- 四阶段编排 — 侦察 → 并行检测 → 综合报告 → 基于证据的误报消除,完全由
CLAUDE.md/AGENTS.md驱动。 - 幂等且可恢复 — 每个阶段会跳过输出已存在的工作;修复问题后重新运行只会刷新过时的部分。
- 机器可读的输出 — 每个技能输出规范的 JSON 格式;
sast-skills export可聚合为 JSON、SARIF 2.1.0 或 HTML 格式,用于 GitHub Code Scanning 和 CI。 - 跨助手支持 — 为 Claude Code (
.claude/skills) 和每个遵循AGENTS.md的助手 (.agents/skills) 提供完全相同的技能。 - 零配置 CLI —
install/update/uninstall/doctor/export,从 GitHub Actions 发布并带有 npm 来源证明(SLSA 见证)。
流程
编排器执行四个阶段:侦察、并行检测、综合和误报消除:
flowchart TD
U(["用户: 运行漏洞扫描"]) --> R{"CLAUDE.md / AGENTS.md 编排器"}
R --> S1["步骤 1 — sast-analysis<br/>代码库和架构映射"]
S1 -->|sast/architecture.md| S2["步骤 2 — 并行漏洞扫描<br/>28 个技能: 侦察、批量验证、合并"]
S2 -->|sast/*-results.md 和 *-results.json| S3["步骤 3 — sast-report<br/>合并并排序"]
S3 -->|sast/final-report.md| S4["步骤 4 — sast-triage<br/>误报消除、<br/>基于证据的严重性调整"]
S4 -->|sast/final-report-triaged.md 和 triaged.json| EXP["npx sast-skills export<br/>JSON, SARIF, HTML"]
EXP --> CS(["GitHub Code Scanning, CI, 仪表板"])
每个步骤都是幂等的:如果其输出文件已存在,编排器将跳过它。修复问题后重新运行扫描,只会刷新过时的部分。
检测内容
所有技能遵循相同的三阶段模式:侦察 → 批量验证(并行子代理,每批 3 个)→ 合并。每个技能都会写入一个人类可读的 Markdown 报告和一个规范的 JSON 发现文件,供 sast-skills export 聚合。
侦察与综合
| 技能 | 角色 |
|---|---|
sast-analysis | 代码库侦察、架构映射、威胁建模 |
sast-report | 将每个类别的发现合并为排序后的报告 |
sast-triage | 移除误报并根据代码库证据调整严重性 |
注入
| 技能 | 漏洞类别 |
|---|---|
sast-sqli | SQL 注入 |
sast-nosql | NoSQL 注入(Mongo, Firestore, DynamoDB) |
sast-ldap | LDAP 过滤器 / DN 注入 |
sast-graphql | 不安全的 GraphQL 文档构建 |
sast-xss | 跨站脚本攻击 |
sast-ssti | 服务器端模板注入 |
sast-rce | 远程代码执行(命令注入、eval、不安全的反序列化) |
sast-xxe | XML 外部实体 |
sast-ssrf | 服务器端请求伪造 |
sast-openredirect | 开放重定向(钓鱼 / OAuth 令牌窃取) |
访问控制与认证
| 技能 | 漏洞类别 |
|---|---|
sast-idor | 不安全的直接对象引用 |
sast-missingauth | 缺少认证 / 损坏的函数级授权 |
sast-jwt | 不安全的 JWT 实现 |
sast-csrf | 跨站请求伪造 |
sast-cors | CORS 配置错误 |
文件、密码学与运行时
| 技能 | 漏洞类别 |
|---|---|
sast-pathtraversal | 路径 / 目录遍历 |
sast-fileupload | 不安全的文件上传 |
sast-crypto | 弱原语、错误模式、IV 重用、弱 PRNG |
sast-prototype | JavaScript 原型污染 |
sast-redos | 灾难性回溯正则 DoS |
sast-race | 竞态条件和 TOCTOU |
数据泄露与供应链
| 技能 | 漏洞类别 |
|---|---|
sast-hardcodedsecrets | 客户端代码中的 API 密钥 / 令牌 / 凭据 |
sast-pii | PII 和凭据泄漏到日志 / 遥测 / 错误页面 |
sast-deps | 已知漏洞依赖项(锁定文件中的 CVE) |
sast-iac | 不安全的 IaC(Dockerfile / Terraform / Kubernetes / GitHub Actions) |
业务逻辑与 LLM 特有
| 技能 | 漏洞类别 |
|---|---|
sast-businesslogic | 价格操纵、工作流绕过、奖励滥用 |
sast-promptinjection | 不可信文本到达 LLM 提示(OWASP LLM #1) |
sast-llmoutput | 未验证的 LLM 输出到达代码 / HTML / SQL / shell 接收器(OWASP LLM #2) |
安装
npx sast-skills install
安装器会询问要面向哪个助手(claude / agents / all)以及是否安装到当前项目或用户主目录(project / global)。要跳过提示:
npx sast-skills install --yes --assistant claude --scope project
如果你的项目已包含
CLAUDE.md或AGENTS.md,安装器默认拒绝覆盖它 — 请备份或传递--force标志。
手动安装(不使用 npx / npm)
如果你无法运行 npx(公司代理、npm 注册表不可访问、离线环境),或者希望固定使用此分支的源代码而非发布的 npm 包,请使用此方式。CLI 安装器只做两件事 — 在项目根目录放置编排器入口文件,并将每个技能的 SKILL.md 镜像到正确的隐藏目录中 — 因此纯 cp -R 可以精确复现。
1. 获取捆绑文件
git clone https://github.com/mstfknn/sast-skills.git
你需要的一切都位于 sast-skills/sast-files/ 下:
sast-files/
├── CLAUDE.md # Claude Code 的编排器入口
├── AGENTS.md # Gemini CLI / Codex / OpenCode / Cursor 的编排器入口
├── .claude/skills/sast-*/SKILL.md # 31 个技能的 Claude Code 格式
└── .agents/skills/sast-*/SKILL.md # 为 AGENTS.md 助手镜像的相同 31 个技能
两个技能树通过 npm run sync 保持同步 — 内容相同,仅目录名不同。
2a. 为 Claude Code 安装
设置 SAST_SRC 为克隆路径,以便下面的命令可以保持可复制粘贴:
export SAST_SRC=/absolute/path/to/sast-skills
cd /path/to/your-project
项目范围(推荐 — 与你的仓库一起版本化):
cp "$SAST_SRC/sast-files/CLAUDE.md" ./CLAUDE.md
cp -R "$SAST_SRC/sast-files/.claude" ./
如果你已使用了项目级别的
CLAUDE.md,请不要覆盖它 — Claude Code 每个项目只读取一个CLAUDE.md。请将编排器内容(四阶段流程)合并到你现有的文件中。
全局范围(技能在所有项目中可用;编排器仍按项目复制):
mkdir -p ~/.claude/skills
cp -R "$SAST_SRC/sast-files/.claude/skills/." ~/.claude/skills/
# 然后在任何你想运行扫描流程的项目中:
cp "$SAST_SRC/sast-files/CLAUDE.md" /path/to/your-project/CLAUDE.md
2b. 为 Gemini CLI(和其他 AGENTS.md 助手)安装
export SAST_SRC=/absolute/path/to/sast-skills
cd /path/to/your-project
cp "$SAST_SRC/sast-files/AGENTS.md" ./AGENTS.md
cp -R "$SAST_SRC/sast-files/.agents" ./
AGENTS.md 是 Gemini CLI、Codex CLI、OpenCode 和 Cursor 都遵守的跨助手约定。如果你的 Gemini CLI 版本查找的是 GEMINI.md,请重命名它 — 内容不变:
mv AGENTS.md GEMINI.md
3. 验证安装
# 项目范围(Claude Code)
ls CLAUDE.md && ls .claude/skills/ | head
# 项目范围(Gemini / AGENTS.md)
ls AGENTS.md && ls .agents/skills/ | head
# 全局范围(Claude Code)
ls ~/.claude/skills/ | head
你应该看到所有 31 个 sast-* 技能目录。在你的助手中打开项目并提示 "运行漏洞扫描" — CLAUDE.md / AGENTS.md 中的编排器将从那里驱动四个阶段。
4. 保持手动安装为最新
cd "$SAST_SRC" && git pull
# 重新运行步骤 2a / 2b 中的 cp 命令以刷新 — 它们是幂等的。
如果你保留了克隆,cd "$SAST_SRC" && git pull && <rerun cp> 相当于 npx sast-skills update 的手动方式。
CLI 命令
| 命令 | 功能 |
|---|---|
npx sast-skills install | 将 CLAUDE.md / AGENTS.md 和技能树复制到你的项目或 $HOME |
npx sast-skills update | 用当前捆绑的技能文件刷新现有安装 |
npx sast-skills uninstall | 移除已安装的技能;除非使用 --force,否则拒绝删除已修改的 CLAUDE.md |
npx sast-skills doctor | 验证安装并报告每个文件的 OK / MISSING / MODIFIED 状态;如有问题则退出并返回非零状态 |
npx sast-skills export --input sast/ --format sarif --output report.sarif | 将 sast/*-results.json 聚合为 JSON、SARIF 2.1.0 或 HTML 格式 |
npx sast-skills export --input sast/ --triaged --format sarif | 优先使用经过误报消除的 sast/triaged.json 而非原始按技能结果 |
npx sast-skills --version | 打印已安装的 CLI 版本 |
安装时标志
| 标志 | 目的 |
|---|---|
--yes | 非交互式;当 stdin 不是 TTY 时需要 |
--assistant <claude|agents|all> | 要安装哪个技能树 |
--scope <project|global> | 安装到 ./.claude/skills/ 还是 $HOME/.claude/skills/ |
--target <path> | 显式安装目标(覆盖 --scope) |
--force | 覆盖预先存在的 CLAUDE.md / AGENTS.md |
--dry-run | 仅打印文件计划而不写入 |
运行扫描
安装后,在你的 AI 助手中打开项目并询问:
运行漏洞扫描
或
在此代码库中查找漏洞
编排器将接管。它会自动运行所有四个阶段,尊重幂等性(重新运行仅捕获缺失的部分),并将所有内容写入项目根目录下的 sast/ 中。
输出文件
| 文件 | 描述 |
|---|---|
sast/architecture.md | 技术栈、架构、入口点、数据流 |
sast/*-results.md | 按漏洞类别的发现(人类可读) |
sast/*-results.json | 规范的机器可读发现(提供给 sast-skills export) |
sast/final-report.md | 按严重性排序的合并原始报告 |
sast/final-report-triaged.md | 经过误报消除的报告 — 移除了误报,根据证据调整了严重性 |
sast/triaged.json | 规范的经过误报消除的发现(sast-skills export --triaged 首选) |
发现模式
每个技能将 sast/<skill>-results.json 写为一个纯发现列表:
{
"findings": [
{
"id": "sast-sqli-0001",
"skill": "sast-sqli",
"severity": "critical|high|medium|low|info",
"title": "SQL injection in /api/user",
"description": "…",
"location": { "file": "src/api/user.js", "line": 42, "column": 10 },
"remediation": "…"
}
]
}
sast-skills export 将这些文件聚合到一个文档中,并包裹在一个 run 信封中 — { "run": { "tool": "sast-skills", "version": "<cli-version>" }, "findings": [...] } — 并标记生成报告的 CLI 版本。误报消除步骤将 sast/triaged.json 写入相同的信封形状。
经过误报消除的发现会添加 triage_status(confirmed|upgraded|downgraded|false_positive)、triage_original_severity(当严重性改变时)以及包含具体代码库引用的 triage_evidence。
CI 集成
GitHub Code Scanning (SARIF)
github/actions/scan/action.yml 中的复合操作:
- uses: mstfknn/sast-skills/.github/actions/scan@main
with:
input: sast/
output: sast-skills.sarif
这将运行 sast-skills export --format sarif 并通过 github/codeql-action/upload-sarif@v3 将结果上传到 Code Scanning。
Pre-commit 钩子
将 hooks/pre-commit 复制到 .git/hooks/pre-commit,使 sast-skills doctor 在每个提交时进行检查。
Docker
docker build -t sast-skills .
docker run --rm -v "$PWD:/work" sast-skills export --input sast/ --format sarif --output report.sarif
捆绑的 Dockerfile 是基于 node:20-alpine 的,并将 sast-skills 设置为入口点。
验证与故障排除
# 安装是否符合预期
npx sast-skills doctor --target . --assistant claude
# 版本检查
npx sast-skills --version
npm view sast-skills version # 注册表上的最新版本
# 升级
npx sast-skills update
如果目标中的每个捆绑文件与安装版本的副本匹配,doctor 退出代码 0;如果任何文件 MISSING 或 MODIFIED,则退出 1。MODIFIED 表示文件与捆绑副本不同 — 如果你编辑了入口文件,这是预期的;否则表示需要运行 update。
贡献
请参阅 CONTRIBUTING.md。开发者循环:
npm install
npm test # vitest 套件(启用 TDD 保护)
npm run sync # 镜像 .claude/skills → .agents/skills
node scripts/scaffold-skill.js sast-foo # 在两个树中创建一个新技能存根
node scripts/register-skill.js sast-foo foo "Foo" "Foo injection description"
npm run lint:md # markdownlint
…
[为翻译截断]