关于 finding-triage
finding-triage 是面向安全团队的单项安全发现评估技能,从验证真实性到确定严重性与处置方式,并生成可用于工单的说明和审计记录。
主要功能
- 01复核发现及其证据
- 02按环境校准严重性
- 03区分误报与加固备注
- 04记录处置决定和审计依据
适用场景
- 01审查扫描器或渗透测试发现
- 02评估 findings.json 中的记录
- 03为安全工单编写处置说明
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ briiirussell/ cybersecurity-skills --skill finding-triage安装后在 Claude Code 中输入/finding-triage确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/findings-format.mdfindings.schema.jsonseverity-calibration.mdto-sarif.mjsvalidate-findings.mjsverification.md详细介绍
发现项分诊 — 单项发现的处置与可辩护的理由说明
本仓库中的其他技能都会生成发现项。本技能负责闭环处理——针对单项发现,逐步判断它是否真实存在、在你的上下文中应定为何种严重程度,以及该如何处理。输出一份可直接用于工单的完整说明,其中包含正确的字段、充分的理由说明,以及即使监管机构在六个月后审阅也经得起检验的审计记录。
已确认的发现项最终会归入五种处置方式之一:已修复、已延期、接受风险、已缓解(平台/配置)或需要重大迁移。对于真实存在的发现项,误报不属于处置方式——它表示判定为不存在发现项。未能追溯到任何影响的缺口最终应作为加固备注处理:不属于发现项,也不定严重程度。
本技能适用于任何来源的发现项:SAST 输出、DAST 扫描器、依赖项安全公告、人工审计、威胁搜寻命中、渗透测试报告、供应商披露、内部红队报告、漏洞赏金提交,或来自其他技能 findings.json 的结构化记录。
交叉引用:
vuln-research:提供 CVE 技术深度分析,为此处的可达性评估提供依据owasp-audit/api-audit处置规则(本技能逐项实施的框架)及其逐项验证流程(references/verification.md)scanner-pipeline:处理批量扫描器输出——在此逐项分诊筛选后的结果security-comms:当发现项需要脱离安全上下文进行沟通时,将处置说明转换为利益相关方易于理解的语言- 任何审计技能——本技能将其发现项作为输入
- references/severity-calibration.md — 本技能概述的完整严重程度规则
- references/findings-format.md —
findings.json记录格式
授权
确认用户拥有此发现项及其所在系统,或已获授权对其进行分诊。分诊过程中会读取代码和配置,有时还会运行复现流程——仅对范围内的系统执行。如果复现流程可能触及生产环境或他人的系统,请停止并先取得明确批准。
输入
以问题到达时的任何形式接收。两种形式需要特殊处理。
findings.json 记录。 如果用户指出某个 findings.json(来自 owasp-audit、api-audit、dependency-audit、secrets-audit、scanner-pipeline、business-logic-testing 或 agent-supply-chain-audit),请索取 fingerprint,或者列出记录供用户选择。先验证文件:
node references/validate-findings.mjs findings.json
然后直接使用记录中的字段,而不是重新推导:location、trace[](入口点 → 汇点)、evidence[]、counterevidence、conditions[],以及(如果存在)severity。格式见 references/findings-format.md。
判定结果。 本仓库审计技能发现的问题会带有三种判定结果之一。根据判定结果开始分流:
| 判定结果 | 含义 | 分流起点 |
|---|---|---|
confirmed | 有完整跟踪链或 PoC;带有严重性等级 | 第 2 步(重新检查),然后第 3 步(重新校准严重性),再到第 4 步 |
needs_validation | 代码支持该问题,但决定性事实在代码之外。有 blockers[] + validation_plan,没有严重性等级 | 执行验证计划或移交他人处理。评级前解决所有阻碍因素。结果:confirmed(转到第 3 步)或 rejected(使用误报模板)。阻碍因素尚未解决时,不要指定严重性等级 |
rejected | 某个命名控制(ruled_out_by)在每条可达路径上都会运行 | 确认该控制仍存在于 ruled_out_by.location,且仍在每条路径上运行。如果是,记录为误报。如果控制已移动或移除,则重新作为候选问题处理 |
旧的“Potential”标签已弃用;仍标记为该标签的任何问题都应视为 needs_validation,并询问其阻碍因素。
分流结果改变记录时,将结果写回记录——verdict、severity、disposition——以确保 JSON 始终是真实信息源。编辑后重新运行验证器。提高判定结果(改为 confirmed 或提高严重性等级)需要新的证据,而不仅仅是不同的看法。
工作流
Agent 与用户一起完成以下步骤。如果用户掌握的问题本身无法揭示的背景信息,请暂停并提出澄清问题。
第 1 步 — 用自己的话重述问题
如果问题来自扫描器,请重述实际的指控内容。扫描器会产生噪声;重述可以过滤掉套话。
好的重述应说明:
- 问题是什么(具体弱点;如适用,注明 CWE)
- 问题在哪里(文件:行号、端点、资源 ARN、主机)
- 可能如何利用(前置条件、攻击者所需的能力)
- 利用后的影响(数据丢失、权限提升、可用性受损)
如果无法清楚地重述,就说明你还不理解。请向用户询问背景信息。
步骤 2 — 这真的属实吗?
按数量计算,自动扫描器报告的发现中有一半是误报。分流时可参考以下问题:
| 问题 | 如果是 | 如果否 |
|---|---|---|
| 易受攻击的代码路径是否如描述所示存在? | 继续 | 误报 — 扫描器发现了一个虚构的问题 |
| 攻击者可控的输入是否能到达该代码路径? | 继续 | 继续,但严重性降低 |
| 漏洞利用的前置条件是否符合你的环境? | 继续 | 严重性降低或判为误报 |
| 是否存在公开的 PoC,或有人确认漏洞已在实际环境中被利用? | 严重性维持 / 上升 | 严重性可能降低 |
| 现有控制措施(WAF、身份验证、网络分段)是否阻止了漏洞利用? | 严重性降低;控制措施成为缓解措施 | 严重性维持 |
边界 + 结果门槛。 每项发现都必须说明以下六点。请逐一记录:
- 信任级别较低的主体 — 谁发起操作(匿名客户端、任何已注册用户、租户 B)
- 被接受的输入 — 对方控制什么,以及输入从哪里进入
- 预期控制措施 — 什么措施本应阻止对方
- 跨越的边界 — 输入跨过了哪条信任边界(用户 A → 用户 B、匿名 → 已验证身份)
- 受影响的主体或资源 — 谁或什么会受到损害
- 具体结果 — 实际观察到的情况,或跟踪代码在接收点执行的操作
缺少任何一点?那它还不算一项发现:
- 没有跨越边界,或受害者就是攻击者(自我 XSS)→ 加固建议或不报告
- 没有被结果绕过的预期控制措施(仅偏离检查清单)→ 加固建议
- 决定性事实在代码之外(代理、IdP、部署标志)→ 需要验证,并将该事实列为阻碍项
- 没有具体结果 → 继续跟踪,或舍弃该项
常见误报模式:
- SAST 在测试文件或死代码中标记问题
- 依赖扫描器标记的包仅存在于
devDependencies中 — 运行时不可达(参见dependency-audit的可达性列) - DAST 标记的路径在实际环境中返回 404,但被 SPA 路由误导
- 公告已过时 — 供应商在 CVE 发布前就已悄然修复问题;你的版本包含该修复
- 模式匹配发现的代码看起来容易受攻击,但它所在的函数从未被调用
- 所谓的“密钥泄漏”实际是可公开的标识符(Stripe
pk_…、Firebase Web 配置、Supabaseanon)。评级前先检查该密钥能执行什么操作 — 参见 references/severity-calibration.md §6
误报判定必须指出具体控制措施。“看起来没问题”不算判定。请指出具体控制措施及其运行位置(文件:行号、配置键),并确认攻击者可到达接收点的每条路径上都会执行该措施。其他路径上的控制措施、泛泛信任的库,或“这是内部环境”都不能排除问题。
应像记录真实发现那样认真记录误报判定。 如果后续扫描器或审计人员再次标记同一问题,此前的误报说明可以省去他们重复调查的工作。
步骤 3 — 结合上下文评估严重性
扫描器给出的 CVSS 或严重性评级只是起点,并非最终结论。分别评估可能性和影响,各用一行说明理由,然后确定总体评级。
规则:总体严重性 ≤ 已证实的影响。 低影响漏洞即使很可能被利用,仍应评为低风险发现。如果无法说明具体损害,严重性就应低于你的直觉判断。
可能导致严重性高于原评级的因素:
- 易受攻击的端点面向互联网,而非仅供内部使用
- 在你的应用中,身份验证的前置条件很容易满足(开放注册),即使 CVE 假设用户“已通过身份验证”
- 易受攻击的数据受监管(PII、PCI 持卡人数据、PHI)——漏洞利用可能导致必须报告的事件
- 存在公开的 PoC,或已观察到主动利用
- 易受攻击的组件位于关键路径中(每个请求都会经过它)
- 缓解措施缺失或薄弱 会降低严重性评级的因素:
- 在你的使用场景中,存在漏洞的代码路径无法触达(阅读补丁,搜索该函数——参见
vuln-research) - 有效的补偿性控制(WAF 会拦截符合该模式的载荷;网络分段会阻止访问)
- 利用漏洞需要的前提条件在你的环境中不存在(特定 OS 版本、特定配置)
- 在你的应用中,身份验证的前提条件难以满足(注册受限、MFA、仅限员工)
- 组件仅用于开发或构建,运行时无法触达
严重性参照标准:
| 级别 | 参照标准 |
|---|---|
| 严重 | 完全绕过核心控制,造成广泛而严重的后果,且几乎没有前提条件或无需前提条件——预认证 RCE、接管任意账户、跨租户访问所有数据、泄露拥有写入权限的生产密钥 |
| 高 | 完全绕过明确的安全控制,并造成实际后果——IDOR 读取或更改其他用户的数据、权限提升、SSRF 访问云凭据 |
| 中 | 削弱控制但未完全绕过,或虽完全绕过某项控制但后果有限 |
| 低 | 实际跨越了边界,但后果轻微;或需要不太可能满足的前提条件 |
判断高或中时,需问:是否完全绕过了控制,且能否明确指出损害? 两者皆是 → 可以考虑评为高。否则评为中或更低。
纵深防御缺口不属于低严重性。 若未追踪到影响——例如 A 层已阻止攻击,只是缺少 B 层——则应记为加固建议:不评定严重性,不设 SLA,另行报告(第 4 步)。
通常不评为高或严重——只有追踪到明确、具体且严重的后果时,才提高评级:
- Self-XSS
- 对非敏感操作的点击劫持
- 缺少安全标头、Cookie 标志或 TLS 配置的小问题
- 单独存在的开放重定向
- “若与其他漏洞链式利用可能造成影响”,但其他环节尚未证实
- 任何需要攻击者已有管理员权限、Shell 访问权限或物理访问权限的情况
- 需要攻击者事先持有受害者秘密信息的会话安全弱点——获取该秘密信息并非易事
高/严重级别验收清单。 六项必须全部满足,否则不能评为高:
- 存在现实且在范围内的攻击路径(代码在已部署的产品中运行)
- 攻击者能够实际获取相应位置
- 已证明影响,而非仅声称存在影响
- 已搜索反证,且未发现任何会限制影响的因素
- 有具体的可达性证据(
file:line跟踪或请求/响应) - 在与客户的复盘中经得起质疑——严谨的漏洞分流会接受将其评为高吗?
若有一项不满足,应降级,而不是删除。 保留该发现,并将其评为你能够合理辩护的级别。
缺少部署证据会降低置信度,不会降低严重性的下限。 如果无法确认生产环境是否配置了 WAF 规则,要么将其标记为 needs_validation 并说明这是阻碍项,要么保留已追踪到的严重性,同时降低置信度。不要仅因无法查看生产环境,就悄悄将已追踪到的高危问题评为低危。
SLA 与严重性分别处理。 严重性描述漏洞本身;修复期限则是组织针对该严重性的政策。请将两者分列,并在组织有 SLA 时采用组织的 SLA。常见的默认值如下:
| 严重性 | 修复 SLA(默认) |
|---|---|
| 严重 | 24–72 小时 |
| 高 | 1–2 周 |
| 中 | 30 天 |
| 低 | 90 天 |
| 加固建议 | 无 SLA——列入待办事项,在方便时修复 |
完整规则、示例以及可公开与机密密钥对照表:references/severity-calibration.md。
第 4 步 — 选择处置方式
| 处置方式 | 适用情况 | 必填字段 |
|---|---|---|
| 立即修复(发布前保持开放,发布后标记为 已修复) | 可在该严重性等级规定的 SLA 内部署补丁或缓解措施 | 修复说明、部署计划、验证方法、负责人、目标日期 |
| 延期(已延期) | 严重性要求采取行动,但受运营条件限制,无法立即修复 | 延期原因、新截止日期、负责人、截止日期前条件发生变化时的告警措施 |
| 接受风险(已接受风险) | 当前配置下不计划修复 | (1)不适用修复的原因,(2)补偿性控制,(3)重新评估触发条件 |
| 已缓解(平台/配置) | 代码未变更,但平台或配置控制现在会阻断相关路径(WAF 规则、出站策略、IdP 设置、关闭的功能标志、网络策略) | 控制措施、配置位置、其已生效的证据、移除该措施的条件、该配置的负责人 |
| 需要重大迁移 | 真正的修复需要进行架构变更——升级框架或主版本、重做身份验证模型、变更数据模型——无法在 SLA 内完成 | 迁移范围、临时缓解措施、目标里程碑、负责人、重新评估日期 |
| 误报 | 实际上并非漏洞(判定为 rejected) | 判定依据、具名控制及其位置、需要谨慎抑制的扫描器规则 ID |
| 加固建议 | 没有可追溯的影响——不构成发现项 | 一句话说明缺少什么、为何有帮助、所需工作量。不填写严重性或 SLA |
**关于立即修复:**决定修复不等于已经修复。在计划修复或审核期间,让 findings.json 中的 disposition 保持未设置。记录仍会保持开放,to-sarif.mjs 也会继续对此发出告警。只有变更已发布,且模板中的验证步骤已针对该变更通过后,才设置为 Fixed;在说明中记录提交或发布信息。过早写入 Fixed 会让 SARIF 移除告警,而漏洞仍然存在。
**关于延期:**严重性不会因为你决定延期而改变。记录“高危,延期至第三季度”是诚实的;因为第三季度还很远就将高危降为中危,则是在粉饰风险。
**关于接受风险:**三个字段都必须填写。缺少任意一个字段的“已接受风险”,实际上都是在悄悄丢弃一项真实发现。最容易漏填的是重新评估触发条件——请指定具体条件(计划升级、依赖项更新、流量模式变化、审计周年)。
**关于已缓解(平台/配置):**漏洞仍然存在于代码中。如果有人移除 WAF 规则或启用该功能标志,漏洞就会再次出现。记录哪些操作会撤销缓解措施,并优先考虑最终通过代码修复。影响不变。你可以重新评估可能性,但只有在有证据表明该控制措施对所有路径都有效时才可以这样做,并在可能性理由中说明这一点。
**关于需要重大迁移:**这不是委婉的“接受风险”。必须立即采取临时缓解措施并设定有日期的里程碑;在迁移完成发布前,该发现仍保持开放。
第 5 步 — 编写处置说明
编写可直接用于工单的说明。根据处置方式使用以下模板之一。
模板:修复
## Finding: [Title]
**Source:** [scanner / audit / advisory] **Fingerprint:** [if from findings.json]
**Severity:** [contextual] (Scanner reported: [original]) **SLA:** [date]
**Likelihood / Impact:** [score — reason] / [score — reason]
**CWE / CVE:** [if applicable]
**Location:** [file:line / endpoint / resource]
### What
[Plain-English description — what the issue is]
### Boundary + result
[Principal → input → control defeated → boundary → affected resource → observed result]
### Why this severity
[Contextual reasoning — what the scanner missed, what your environment adds]
### Fix
[Specific change — code diff, config update, dependency upgrade]
### Verification
[Concrete test — adversarial input + observed result that proves the fix holds]
- Run [command / test case]
- Observe [response / behavior]
### Owner: [name]
### Target deploy: [date]
模板:延期
## Finding: [Title] — DEFERRED
**Severity:** [unchanged]
**Original target:** [original SLA date]
**New target:** [date]
### Why deferred
[Operational constraint — release freeze, dependency on third party, etc.]
### Risk during deferral window
[What's the exposure? What controls reduce it?]
### Alerting / conditions that would escalate
[What would force action sooner than the new target?]
### Owner: [name]
### Re-evaluation: [date — usually before new target]
模板:接受风险
## Finding: [Title] — ACCEPTED RISK
**Severity:** [contextual]
**Approver:** [name + role]
**Date accepted:** [date]
### Why fix doesn't apply
[Cost tier, dependency version constraint, deployment topology, vendor limitation, etc. — be specific]
### Compensating controls
- [Control 1 — what it is, why it reduces impact / likelihood]
- [Control 2]
- ...
### Re-evaluation trigger
[Specific condition — plan upgrade, dependency bump, traffic pattern change, calendar anniversary]
- Trigger: [what would change this decision]
- Calendar review: [date — at minimum, annually]
### Approvals
- [ ] Engineering owner: [name, date]
- [ ] Security: [name, date]
- [ ] (if required) Compliance / Legal: [name, date]
模板:已缓解(平台/配置)
## Finding: [Title] — MITIGATED (PLATFORM/CONFIG)
**Severity:** [as rated] **Code still vulnerable:** yes
**Control:** [WAF rule / egress policy / IdP setting / flag — exact name or ID]
**Configured in:** [system + path / console location / IaC file:line]
### Evidence the control is active
[Request blocked with response X; config export; screenshot reference; date checked]
### What would undo it
[Rule removal, config drift, region/environment without the control]
### Long-term fix
[Code change, and whether it's planned]
### Owner of the control: [name / team]
### Re-check: [date or trigger — e.g. every WAF policy change]
模板:需要重大迁移
## Finding: [Title] — REQUIRES MAJOR MIGRATION
**Severity:** [unchanged] **Original SLA:** [date]
### Why a normal fix doesn't apply
[Framework EOL, major-version upgrade, auth or data model change — scope it]
### Interim mitigation (in place now)
[What reduces exposure until the migration ships]
### Migration plan
- Milestone: [target date / release]
- Owner: [name]
- Tracking: [epic / ticket]
### Re-evaluation: [date]
模板:误报
## Finding: [Title] — FALSE POSITIVE
**Scanner:** [name + rule ID]
**Original severity:** [as reported]
### What the scanner claimed
[Restate the claim]
### Why it's not real
[Specific evidence — code path not reachable, version contains the fix, etc.]
**Ruled out by:** [control] at [file:line / config] — runs on every reachable path
### Suppression decision
- [ ] Suppress this exact finding (location + rule ID)
- [ ] Add allow-list rule (with care — broad suppression breeds blind spots)
- [ ] No suppression — re-evaluate if it returns
### Determination by: [name, date]
### Reviewed by: [name, date — for non-trivial suppressions]
模板:加固建议
## Hardening note: [Title] (not a finding — no severity)
- **Gap:** [what's missing]
- **Why no finding:** [which control already prevents it / which gate element is missing]
- **Would help because:** [defense-in-depth value]
- **Effort:** [S / M / L]
步骤 6 — 验证撰写内容
提交之前:
- 未来的你(或审计人员)在 12 个月后阅读这份内容时,能否在没有其他背景信息的情况下理解该决定?
- 撰写内容是否列出了全部六项边界 + 结果要素,或说明缺少哪一项(以及因此为何它属于加固说明或需要验证)?
- 整体严重性是否不高于你实际展示的影响?对于 High/Critical,是否通过了全部六项验收检查?
- 验证步骤是否具体到让原作者以外的其他人也能执行?
- 对于 Accept Risk:三个必填字段是否都填写了具体内容,而非空话(“已实施标准控制”不算补偿性控制)?
- 对于 Mitigated:是否有证据表明控制措施目前有效,并且指定了负责人?
- 严重性是否反映了你的环境,而不只是扫描器的默认值?
- 如果输入是
findings.json记录:是否写回了 verdict、severity 和 disposition,且验证器仍能通过? - 是否有记录标记为
Fixed,但修复尚未发布并验证?在完成之前,清除该 disposition。
何时升级处理
以下发现不应由单个工程师单独分类处置:
- 任何 Critical 发现
- 任何可在预认证情况下利用的发现
- 任何影响受监管数据(PII / PCI / PHI)的发现
- 任何存在公开 PoC 或正在被积极利用的发现
- 任何拟议 disposition 为 Accept Risk、Mitigated(平台/配置)或 Requires major migration,且严重性为 High 或更高的发现
这些发现应交由第二位审核者(Tier 3 / 安全团队 / 政策中指定的审批人)审核。
输出格式
主要输出是 disposition 撰写内容本身(见上方模板)。对于涵盖多个发现或批量导入的分类会话,请进行汇总:
# Finding Triage Session
## Source: [scanner / audit / report / findings.json path]
## Date: [date]
## Triaged by: [name]
### Summary
| Finding | Fingerprint | Verdict | Original severity | Contextual severity | SLA | Disposition |
|---------|-------------|---------|-------------------|---------------------|-----|-------------|
### Detail
[Per-finding writeup using the appropriate template]
### Needs validation (no severity yet)
| Finding | Blocker | Validation plan | Owner |
|---------|---------|-----------------|-------|
### Hardening notes (not findings)
- [one line each — gap, why it would help, effort]
### Related candidates (not triaged here)
| Candidate | Location | Why it's related | Hand to |
|-----------|----------|------------------|---------|
Things you noticed while triaging: the same pattern on a sibling route, a second call site of the vulnerable function, the control that would have caught it missing elsewhere. They have no verdict yet, so don't give them a severity or a `findings.json` record in this session. Name the skill that should review them (`owasp-audit`, `api-audit`, `dependency-audit`, ...), or triage each one separately.
### Escalations
[Findings that need senior review or approval]
边界
- 此技能仅处理用户有权分类和处置的发现
- 严重性判断和 Accept Risk disposition 会影响组织的风险状况——对于 High+ 发现,请确认列出的审批人确实已批准;不要伪造签核
- 误报判定应以证据为依据,不能将“我们不想修复”重新包装成误报——如果用户想把真实发现标为 FP,应予以反对
- 不要把真实发现重新标记为加固说明来掩盖问题:只有在无法追溯到任何影响时,才属于加固说明
- 拒绝帮助降低严重性以规避披露或审计义务
- 复现必须保持无破坏性且在范围内——不得利用生产数据,也不得测试用户不拥有的系统
- 如果发现暴露了正在发生的事件,应移交给
incident-triage——处置分类适用于常规状态下的发现,而非紧急事件
参考资料
- references/severity-calibration.md — 边界 + 结果门槛、锚点、过度评级清单、High/Critical 检查表
- references/findings-format.md —
findings.jsonverdict 和字段;validate-findings.mjs、to-sarif.mjs - Cloudflare security-audit-skill(MIT)— 边界与结果要求、按 verdict 组织的发现记录(转述)
- Strix severity calibration(Apache-2.0)— 过度评级清单以及 High/Critical 验收检查(转述)
- CVSS v4.0 规范 —
first.org/cvss - EPSS — Exploit Prediction Scoring System(FIRST.org)
- NIST SP 800-30(风险评估指南)
- “FAIR”(Factor Analysis of Information Risk)— 如需以金额为单位做出决策,可使用定量风险框架
- ISO 27005 — 风险管理
- 《Measuring and Managing Information Risk》— Jack Freund、Jack Jones(FAIR 著作)
- OWASP 风险评级方法