mcpField
S
snyk-remediation

snyk-remediation

github.com/incu-tech安全178 次安装7 周前更新
代码仓库

关于 snyk-remediation

以 Snyk 扫描结果为依据的安全漏洞处理流程,涵盖问题分级、修复计划、实施和复测。它通过用户确认来界定范围并批准计划,避免未经同意直接修复。

主要功能

  1. 01收集 SAST 与 SCA 扫描结果
  2. 02按用户指定范围筛选问题
  3. 03制定逐项修复计划并等待批准
  4. 04复测并记录解决情况
  5. 05通过确认流程准备 PR

适用场景

  1. 01整理项目中的 Snyk 漏洞发现
  2. 02优先处理指定严重级别的问题
  3. 03跟踪漏洞修复及复测结果

MCP 相关

流程调用 Snyk MCP 工具 `snyk_trust`、`snyk_code_scan` 和 `snyk_sca_scan` 来信任项目路径并运行扫描。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/incu-tech/incuway --skill snyk-remediation

安装后在 Claude Code 中输入/snyk-remediation确认已加载。

附带文件agents/openai.yaml

详细介绍

Snyk 修复流程

一个由关卡驱动的工作流,用于查找并修复 Snyk 检测到的安全漏洞,避免对范围或可接受风险妄下判断。先收集信息并了解扫描背景,然后依次进行扫描、分类、规划、修复、验证,并在关键决策点获得用户明确确认后创建 PR。未经批准的计划不得应用任何修复。


仓库资格检查(先于所有其他操作)

在 Phase 0 之前,检查 ~/.ways/config.yaml 中的 blacklist(格式:incu-base 的 global-config 规则,始终启用) 是否匹配当前仓库。如果匹配,告知用户该仓库已被 incu-way 列入黑名单,并询问是仍要继续(仅限本次例外)还是停止——在用户回复之前,不得运行任何阶段。 文件不存在或没有匹配项:正常继续。


Phase 0 — 信息收集与扫描

目标: 收集 SAST 和 SCA 扫描检测到的所有当前漏洞。

步骤
  1. 扫描前确认信息收集背景:
    • 要扫描的项目绝对路径
    • 用户希望仅审查、分类还是修复
    • 已知的紧急程度、环境或业务限制
    • 用户希望考虑的任何先前扫描背景
  2. 如果项目文件夹尚未获信任,先使用项目绝对路径调用 snyk_trust。
  3. 使用 snyk_code_scan MCP 工具运行 SAST 扫描:
    path: <absolute project path>
    severity_threshold: low
    
  4. 使用 snyk_sca_scan MCP 工具运行 SCA 扫描:
    path: <absolute project path>
    severity_threshold: low
    all_projects: true
    
  5. 收集两份结果中的所有问题。

如果 snyk_trust、snyk_code_scan 或 snyk_sca_scan 不可用,或在返回发现结果前失败,请在 Gate 1 之前停止,报告确切缺失的工具或故障,并请用户安装/配置 Snyk 或提供扫描输出。不得编造发现结果,也不得根据过时数据继续制定修复计划。

Phase 0 防护措施
  • 不要假设用户希望修复所有发现的问题。扫描提供证据;范围由用户确定。
  • 不要仅凭技术严重程度推断业务优先级。
  • 如果路径、扫描目标或期望的修复范围不明确,请先澄清再继续。
Phase 0 退出条件

进入 Phase 1 之前,Claude 应能够说明:

  • 使用的项目路径和扫描目标
  • 用户希望仅审查、分类还是修复
  • 已知的业务或环境限制
  • 发现列表反映的是实际扫描证据,而非假设

Phase 1 — 发现结果报告

目标: 以清晰、可执行的格式向用户展示所有发现结果。

报告格式

创建一个 Markdown 表格,每个发现结果占一行:

# Snyk Security Findings — {YYYY-MM-DD}

## Summary
- SAST issues: {N} (Critical: X, High: X, Medium: X, Low: X)
- SCA issues: {N} (Critical: X, High: X, Medium: X, Low: X)
- Total: {N}

## Findings

| # | Type | Severity | Title | File / Package | CWE / CVE | Impact | Fix available |
|---|------|----------|-------|----------------|-----------|--------|---------------|
| 1 | SAST | High | SQL Injection | `lib/db/queries/contacts.ts:42` | CWE-89 | Attacker can exfiltrate DB data via crafted input | Yes — sanitize input |
| 2 | SCA  | Critical | Prototype Pollution | `[email protected]` | CVE-2019-10744 | Remote code execution via crafted payload | Yes — upgrade to `[email protected]` |

列定义:

  • 类型: SAST(源代码)或 SCA(依赖项)
  • 严重程度: Critical / High / Medium / Low
  • 标题: Snyk 问题标题
  • 文件 / 软件包: 对于 SAST:filePath:line。对于 SCA:package@version
  • CWE / CVE: SAST 使用 CWE,SCA 使用 CVE(如果有)
  • 影响: 用一句话说明攻击者在利用该漏洞后可能造成的后果
  • 有可用修复: 是(附简要说明)或否
Gate 1 — 范围确认

展示表格后:

  • 询问用户:“这些是发现的问题。你希望修复哪些严重程度级别?(例如,Critical + High,或全部。)我会根据你的回答确定修复计划的范围。”
  • 停止。在用户确定范围之前,不得继续。

不得将扫描输出本身视为修复授权。Gate 1 用于确定哪些发现确实属于修复范围。


隔离设置(紧接 Gate 1 之后)

写入任何文件之前,询问用户希望如何隔离工作:

你希望我在当前检出中创建一个新分支进行操作,还是创建一个单独的 git worktree?

严格按照用户的回答操作: 询问后停止;在用户做出选择前,不得创建分支或 worktree。

如果当前检出存在未提交更改,在切换分支或创建 worktree 之前停止并询问。

选项 A — 在当前检出中创建分支
# Run from the repo root
git switch develop
git pull --ff-only
git switch -c fix/security-{slug}

后续所有工作——文档、代码、提交——都在当前检出中的此分支上进行。切勿直接向 develop 或 main 写入文件。

选项 B — 使用单独的工作树

仅在 .worktrees/ 下创建工作树。不要向用户询问路径。

# Run from the repo root
git fetch origin develop
mkdir -p .worktrees
git worktree add .worktrees/security-{slug} -b fix/security-{slug} origin/develop

后续所有工作——文档、代码、提交——都仅在此工作树内进行。切勿直接向 develop 或 main 写入文件。


状态跟踪 — .ways/state.json

遵循 ways/v1alpha1 状态契约——规范的 .ways/state.json 格式(schemaVersion 为 2),该格式随 始终启用的 state-contract 规则一同提供;ways add 会将该规则添加到项目中,因此你已了解相关内容(无需查找路径)。对于维护人员,此仓库中的源文件位于 ways/rulepacks/state-contract/。不要在此技能中复制或臆造架构。

特定于此工作流的值:

  • flow:security
  • way:incu/security · discipline:security(可选的 wayVersion 来自 way 清单)
  • 分支模式:fix/security-{slug}
  • 初始 phase:findings
  • isolationType:根据隔离方式选择 branch 或 worktree
  • 文档:docs/security/{slug}/FINDINGS.md、docs/security/{slug}/PLAN.md、docs/security/{slug}/RESOLUTION.md
  • Gate:plan、resolution、pr-develop、pr-main

会话开始时,如果 .ways/state.json 存在,则读取它。如果其 branch 与当前 fix/security-{slug} 分支匹配,报告当前阶段、下一步和待处理的 Gate,并从该状态继续。如果文件不存在,或文件存在但其 branch 不匹配(从已合并事项继承的过期文件),则从阶段 0 开始,并在 Gate 1 后完成所选隔离设置后,立即在 .ways/state.json 创建或覆盖该文件。每次转换阶段时,也要更新 lastPhase(即将离开的阶段)。

更新节点(阶段 → 写入内容):

时机phase文档 / Gate / 步骤
写入 FINDINGS.mdfindingsFINDINGS.md → approved
起草 PLAN.mdplanPLAN.md → in-review
Gate 2 通过(计划)implementationPLAN.md → approved;Gate plan → passed;生成 steps——每个纳入范围的发现对应一项,且状态均为 todo
修复每项发现implementation将对应步骤标记为 in-progress → done(或 blocked)——每项发现都要立即写入状态文件,不能批量拖到最后
写入 RESOLUTION.mdvalidationRESOLUTION.md → approved
Gate 3 通过(解决方案)validationGate resolution → passed
打开 fix→develop PRpr-developGate pr-develop → 仍为 pending;将其 url 设为 PR 链接
PR 合并到 developpr-developGate pr-develop → passed
打开 develop→main PRpr-mainGate pr-main → 仍为 pending;将其 url 设为 PR 链接
PR 合并到 maindoneGate pr-main → passed

在 Gate 2 生成的 steps(每个纳入范围的发现对应一项)会显示在看板上,作为修复进度。

不要自行提交 .ways/state.json——只需写入它。当用户希望保存检查点时,建议调用 incu-way-prepare-pr,它会将该检查点与此阶段的文档和代码一并提交。


阶段 2 — 记录发现

目标: 将发现报告存档,作为审计轨迹的入口。

保存位置

保存到所选工作位置:

docs/security/{YYYY-MM-DD}-{short-slug}/FINDINGS.md

Slug: 用 2–4 个词概括主要问题类型的 kebab 格式摘要,例如:

  • 2026-05-15-xss-sqli-drizzle
  • 2026-03-10-prototype-pollution-deps
FINDINGS.md 结构
# Security Findings — {YYYY-MM-DD}

## Scan metadata
- Date: {YYYY-MM-DD}
- Tool: Snyk (SAST + SCA)
- Branch scanned: {branch name}
- Scope agreed: {e.g., Critical + High}

## Findings table
{paste the full table from Phase 1}

## Out of scope
{List findings the user chose NOT to fix, with a brief reason}

保存后:

  • 说明:"发现已记录在 docs/security/{slug}/FINDINGS.md。现在我将针对已确认的范围起草修复计划。"
  • 直接进入阶段 3(无需 Gate——用户已在 Gate 1 确认范围)。

阶段 3 — 修复计划

目标: 为每项纳入范围的发现设计具体且便于审查的修复方案。

保存位置
docs/security/{slug}/PLAN.md
PLAN.md 结构
# Remediation Plan — {YYYY-MM-DD}

## Branch
`fix/security-{slug}`

## Isolation mode
current checkout branch | separate worktree

## Findings to fix

### Finding #1 — {Title} ({Severity})
- **Type:** SAST / SCA
- **Location:** {file:line or package@version}
- **Root cause:** {one sentence}
- **Fix approach:** {concrete action: upgrade X to Y / sanitize input at line Z / replace API call / etc.}
- **Risk of fix:** Low / Medium / High — {why}
- **Verification:** {how to confirm it's fixed: re-scan + specific test}

### Finding #2 — ...
Gate 2 — 计划审批

编写计划后:

  • 说:“修复计划已准备就绪,位于 docs/security/{slug}/PLAN.md。请在我开始编码前,审阅每项发现的修复方案。”
  • 停止。在用户表示 OK 前不要继续。

第 4 阶段 — 实施

目标: 在用户选择的隔离分支或工作树中应用修复。

设置

继续使用第 2 阶段前选择的隔离模式。除非用户要求更改模式,否则不要创建第二个分支或工作树。

规则
  • 一次修复一项发现。每修复一项后,建议调用 incu-way-prepare-pr 来提交;不要自行提交:
    fix(security): {finding title} — {CWE or CVE}
    
    Resolves finding #{N} from docs/security/{slug}/FINDINGS.md
    Fix: {one-line description of what changed}
    
  • 对于 SCA 升级: 更新 package.json,运行 pnpm install,并确认没有破坏对等依赖。
  • 对于 SAST 修复: 应用代码更改,并添加或更新一个用于测试易受攻击路径的测试。
  • 每次修复后、建议提交前,运行 pnpm typecheck && pnpm lint && pnpm test。
进度跟踪

随着进度更新 PLAN.md——修复每项发现后,将其标记为对应的提交 SHA:

- **Status:** Fixed in `abc1234`

第 5 阶段 — 验证

目标: 确认所有修复均有效,且未引入回归问题。

步骤
  1. 重新运行 SAST 扫描:
    snyk_code_scan — path: <absolute path to the selected working location>, severity_threshold: low
    
  2. 重新运行 SCA 扫描:
    snyk_sca_scan — path: <absolute path to the selected working location>, severity_threshold: low, all_projects: true
    
  3. 运行完整测试套件:pnpm typecheck && pnpm lint && pnpm test && pnpm build
解决情况文档

保存 docs/security/{slug}/RESOLUTION.md:

# Resolution Report — {YYYY-MM-DD}

## Re-scan results
- SAST re-scan: {N issues remaining} (was {N before})
- SCA re-scan: {N issues remaining} (was {N before})
- Fixed: {list of finding titles resolved}
- Remaining (out of scope): {list}

## Test suite
- `pnpm typecheck`: ✅ / ❌
- `pnpm lint`: ✅ / ❌
- `pnpm test`: ✅ / ❌
- `pnpm build`: ✅ / ❌

## Evidence
{Paste key output from re-scans — zero-issue confirmation or remaining out-of-scope items}
Gate 3 — 验证签核

编写解决情况文档后:

  • 说:“修复已应用并通过验证。解决情况报告位于 docs/security/{slug}/RESOLUTION.md。所有范围内的发现均已解决,测试全部通过。请在我创建 PR 前进行审阅。”
  • 停止。等待用户确认。

第 6 阶段 — Pull Request

目标: 通过经过审阅的 PR 合入安全修复。

分支流程
fix/security-{slug}  →  develop  →  main
                         (PR 1)     (PR 2)
PR 1 — fix/security-{slug} → develop

Gate 3 通过后,建议调用 incu-way-prepare-pr,推送 fix/security-{slug} 并向 develop 创建 PR。不要自行推送或运行 gh pr create。

供 incu-way-prepare-pr 使用的建议 PR 标题/正文:

Title: fix(security): {short summary of what was fixed}

PR 正文必须包含:

  • 摘要: 修复了哪些漏洞(类型、严重程度、数量)。
  • 发现: 链接到 docs/security/{slug}/FINDINGS.md。
  • 计划: 链接到 docs/security/{slug}/PLAN.md。
  • 解决情况: 链接到 docs/security/{slug}/RESOLUTION.md。
  • 检查清单: snyk-code ✅、snyk-deps ✅、typecheck ✅、lint ✅、tests ✅、build ✅。

创建 PR 后,分享 PR URL。停止。未经用户批准,不要合并。

PR 2 — develop → main

PR 1 合并后,再次建议调用 incu-way-prepare-pr,创建从 develop → main 的 PR:

Title: release(security): {slug}
Body: Promotes security remediations from fix/security-{slug}. See docs/security/{slug}/ for full audit trail.

创建后,分享 URL 并等待用户批准。


快速参考 — 各 Gate

Gate触发条件要说的话阻塞条件
1展示发现表格“你想修复哪些严重程度级别?”用户确定范围
2编写 PLAN.md“计划已准备就绪,位于 docs/security/{slug}/PLAN.md。请审阅。”用户表示 OK
3编写 RESOLUTION.md“修复已通过验证。请在创建 PR 前审阅解决情况报告。”用户表示 OK
4用户确认建议调用 incu-way-prepare-pr 创建 fix→develop 的 PR;用户运行后分享 URL用户批准 PR
5PR 1 合并建议调用 incu-way-prepare-pr 创建 develop→main 的 PR;用户运行后分享 URL用户批准 PR

每次扫描的文档布局

docs/security/{YYYY-MM-DD}-{slug}/
  FINDINGS.md    — raw scan results + agreed scope  (Phase 2)
  PLAN.md        — fix approach per finding          (Phase 3)
  RESOLUTION.md  — re-scan evidence + test results   (Phase 5)

不要做的事

  • 在 Gate 2(计划审批)通过前,不要应用任何修复。
  • 未先征求用户意见,不要修复范围外的发现。
  • 未得到用户明确指示,不要擅自推断修复范围、可接受风险或业务优先级。
  • 如果预期范围或修复取舍仍不明确,不要直接将扫描结果转化为修复计划。
  • 不要跳过 Phase 5 中的重新扫描——仅通过测试并不能确认漏洞已修复。
  • 如果 RESOLUTION.md 未显示重新扫描结果干净,不要创建 PR。
  • 不要直接合并——始终通过 PR 进行,即使只是微不足道的依赖升级。
  • 未得到用户明确指示,不要使用 .snyk 忽略规则屏蔽 Snyk 发现。
  • 在选择隔离模式前,不要将 FINDINGS.md、PLAN.md 或任何其他文件写入 develop/main——Gate 1 通过后会立即设置分支或工作树,从一开始就应将所有文件放入所选工作位置。

评论

支持 Markdown