关于 reporting-security-findings
这是一项安全报告撰写技能,帮助将已验证的漏洞证据整理为可复现的发现和可执行的评估报告,面向审计人员、渗透测试人员及漏洞赏金报告者。内容涵盖严重性评估、按读者撰写摘要和协调披露。
主要功能
- 01结构化且有证据支撑的发现
- 02可复现概念验证的编写指引
- 03结合业务影响评估 CVSS
- 04针对不同读者组织报告
- 05协调披露指引
适用场景
- 01撰写渗透测试或代码审计报告
- 02准备漏洞赏金提交
- 03与工程团队确定发现项优先级
- 04规划未修复漏洞的披露
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ trilwu/ secskills --skill reporting-security-findings安装后在 Claude Code 中输入/reporting-security-findings确认已加载。
详细介绍
安全问题报告
报告本身就是成果。未被理解的问题不会得到修复,无法复现的问题则会受到质疑。评估所创造的大部分价值,都会在报告中被摧毁或保留下来。
适用场景
- 编写单个漏洞的报告
- 编写渗透测试、代码审计或红队报告
- 向漏洞赏金计划提交报告,或分诊收到的提交
- 评定严重性,并与工程团队讨论优先级
- 为尚未修复的问题规划协调披露
不适用场景
- 发现漏洞——先使用相关的测试或审计技能
- 整理报告所依据的原始记录(来源、工件登记表、证据、无果的尝试)——使用
maintaining-engagement-state;本技能会使用这份记录 - 事件叙述和事后复盘——使用
responding-to-incidents - 以映射合规框架为首要目标——这是不同的文档,面向不同的受众
问题的构成
每个问题都按以下顺序回答五个问题:
### F-03 Tenant isolation bypass in report export [High]
**Summary**
An authenticated user of any tenant can export reports belonging to other
tenants by supplying an arbitrary report ID to `GET /api/v2/reports/{id}/export`.
**Impact**
Full read access to other customers' report data, including the financial
figures and contact records those reports contain. Any customer account —
including a self-service trial — is sufficient. This is a cross-tenant
confidentiality breach with likely contractual and regulatory consequences.
**Affected**
`api/handlers/reports.go:214` (`handleExport`), deployed in production as of
commit `a1b2c3d`. Reproduced on staging 2026-07-24 14:02 UTC.
**Reproduction**
1. Authenticate as `trial-user@tenant-a` and obtain a session token.
2. Note your own report ID from `GET /api/v2/reports` (e.g. `1041`).
3. Request a neighbouring ID:
curl -H "Authorization: Bearer $TOKEN" \
https://staging.example.com/api/v2/reports/1042/export -o out.csv
4. `out.csv` contains tenant B's data. Confirmed with IDs 1042, 1043, 1055.
**Root cause**
The handler looks the report up by primary key and checks only that the
session is valid. The tenant scope present on the list endpoint
(`WHERE tenant_id = ?`) is absent from the export query.
**Remediation**
Add the tenant predicate to the export lookup, and enforce it at the data
access layer rather than per handler so new endpoints inherit it:
SELECT ... FROM reports WHERE id = ? AND tenant_id = ?
Then audit the remaining 14 handlers that call `findByID` without a scope —
listed in Appendix B.
**References**
CWE-639, OWASP API1:2023 Broken Object Level Authorization
让问题切实可处理的规则:
- 每个问题单独成项。 把十个 IDOR 合并成“授权问题”,必然会导致修复不完整。
- 精确定位。 列出文件、行号、端点、提交,以及复现问题的环境。
- 提供他人无需向你提问即可执行的复现步骤。 包括设置、请求和观察到的结果,而不只是有效载荷。
- 说明根本原因,而不只是症状。 只修复症状会留下同类问题。
- 明确写出修复措施。 “验证输入”不算修复方案。
- 列出变体。 如果你发现一个实例并怀疑还有更多,应说明检查了什么、没有检查什么。
- 针对实际发布的版本重新验证。 在将问题写入报告前,确认易受攻击的代码并未在你尚未拉取的分支上修复(
git log --oneline <checkout>..origin/main -- <file>)。一个已经修复的问题就足以让读者开始怀疑报告中的其他内容。
问题从草稿转为正式报告前必须检查的不变量
上述规则中有四条足够机械化,可以逐项检查,而非依赖判断。对每个问题都执行这些检查;每条规则都对应着报告中实际出现过的一种失误。
- 每个问题至少引用一项证据——命令及其输出、请求与响应、崩溃信息或屏幕截图。唯一依据是代码审查的问题只是候选项,而非正式问题。应明确标记。
- 状态已确认与信心不足不能并存。 如果你不敢打赌,它仍然只是候选项。应降低状态,或明确说明哪些信息可以确定问题。报告中最常见的情况之一,就是推测性问题在写入报告的过程中获得了不应有的权威性。
- 每条复现步骤都无需向你提问即可执行,或者明确指出其受限环境——离线样本、仅限实验室的目标,或读者必须提供的凭据。无法复现的问题,在修复会议上就无法为其辩护。
- 声称已获得访问权限或数据,就必须有针对该具体主张的证据。 “完整读取数据库”需要提供你实际读取到的一行记录,而不能只提供一个可注入参数,再推断其背后的数据。可达性不等于影响。
如果某个问题未通过其中一项检查,不要悄悄将其删除:应将其移入候选项待办列表,并附上原因,以便后续审查时知道需要什么才能将其提升为正式问题。关于由独立审查者将候选项提升为正式问题时如何评级,请参阅 orchestrating-vulnerability-research。
严重性
CVSS 是通用的衡量标准,但它对抽象层面上的漏洞进行评分。 先用 CVSS 评分,再单独说明业务影响——工程团队根据后者确定优先级。
CVSS 4.0 base vector example:
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N → 6.9 Medium
然后根据实际情况调整,并说明原因:
| 因素 | 提高优先级 | 降低优先级 |
|---|---|---|
| 暴露面 | 面向互联网、无需身份验证 | 仅限内部、需要管理员权限 |
| 数据 | 受监管数据、客户数据、凭据 | 合成数据、公开数据 |
| 漏洞利用成熟度 | 公开漏洞利用代码、正在遭受利用 | 理论上的利用方式、复杂攻击链 |
| 补偿性控制措施 | 无 | WAF 规则、网络分段、监控 |
| 影响范围 | 跨租户、整个集群 | 单个账户、单条记录 |
对于 SaaS 产品,若一个 CVSS 中危漏洞破坏了租户隔离,无论评分是多少,都属于 P1。应明确说明这一点,而不是让评分替你争辩。反过来,也不要抬高评分:如果报告中的所有问题都被评为严重,分诊时就会被直接忽略。
链式发现:分别报告各个组成问题,同时将攻击链作为独立发现报告,并给出链式问题的严重性。攻击链体现的是攻击者的行为;各个组成问题则是工程团队需要修复的内容。
概念验证
根据证明目标所需的程度调整 PoC:
- 足以证明对目标数据的控制。 如果
id=1042返回了另一个租户的记录,就足以证明漏洞。导出整个数据库并不能让证明更有力。 - 默认采用非破坏性方式。 不要通过修改或删除数据来演示写入权限;可以在自己拥有的记录中写入无害标记,或者在不造成实际影响的情况下演示授权决策。
- 对真实数据进行脱敏。 如果证据中包含客户记录,应在报告中将其脱敏,并将原始证据单独存储并设置访问控制。
- 说明你的操作。 如果你创建了账户、上传了文件或留下了其他产物,应逐项列出,以便清理。
对于内存安全和漏洞利用类发现,通常适当的深度是提供一个指令指针受控的崩溃,并分析其可利用性。只有在委托任务明确要求时,才应在报告中提供武器化漏洞利用代码。
报告
1. Executive summary — 1 page, no jargon, answers "how bad and what now"
2. Scope and methodology — what was tested, how, and with what access
3. Coverage and limitations — what was NOT tested, and why
4. Findings — ordered by severity, each self-contained
5. Strategic recommendations— themes across findings, not per-finding fixes
6. Appendices — tooling, raw output, evidence index, retest results
执行摘要是写给只会阅读这一部分的人看的。 写清三件事:用一句话说明整体风险态势、指出两三个重要发现,以及说明需要对方做出什么决策。不要包含 CVSS 向量、工具名称,也不要写“我们运行了 Nessus”。
覆盖范围和限制是保障各方权益的部分。 说明时间范围、你拥有的账户和环境、无法访问的组件,以及受委托方要求不得开展的测试。报告若对限制只字不提,就会让人以为覆盖范围超出了实际情况;这种沉默会让漏掉的漏洞演变成争议。
战略建议体现了评估能够赢得后续合作的价值:指出共性问题。“授权是在各个处理程序中而非数据层强制执行的;14 个发现中有 9 个源于这一根本原因。”这句话比那 9 个发现更有价值。
面向受众撰写
| 读者 | 他们想了解什么 | 应提供什么 |
|---|---|---|
| 高管 | 风险和决策 | 一页内容、通俗语言、业务后果 |
| 工程经理 | 优先级和工作量 | 严重性、根本原因、修复范围 |
| 工程师 | 如何立即修复 | 具体位置、复现步骤、明确的修改方案 |
| 合规/审计人员 | 证据和映射 | 方法论、覆盖范围说明、框架参考 |
面向工程师撰写发现,面向高管撰写摘要。不要折中写成两边都不适用的内容。
语气:描述缺陷,而非开发者。“导出处理程序缺少租户条件”——而不是“开发者忘记了”。报告会被转发,指责性的报告会让下一次合作更加困难。
披露
对于你不拥有的软件中的发现:
Day 0 Report privately: security.txt, /security, GitHub advisory, CERT
Day 0-7 Acknowledge receipt; agree a timeline
Day 45 Check in; offer help reproducing
Day 90 Standard public disclosure deadline (adjust for severity and
exploitation in the wild — actively exploited issues warrant faster
public warning; complex fixes may warrant an extension you agree to)
- 首次联系时给出明确的期限,并遵守期限。
- 如果问题影响到已有其他用户的已发布软件,请申请 CVE。
- 在修复方案广泛可用之前,不要发布漏洞利用代码;应改为描述影响和缓解措施。
- 如果供应商没有回应,应升级给 CERT/CSIRT 协调方,而不是直接公开。
- 切勿为了“完善报告”而超出授权范围进行测试,也绝不要利用发现作为施压筹码。这两种做法都会把研究贡献变成法律问题。
提交漏洞赏金报告前,先阅读项目的范围和规则;每次提交只报告一个问题,并附上分诊人员在内部说明奖金发放理由所需的影响说明。
应当摒弃的自我辩解
- “他们会明白我的意思。” 他们不会,也不会追问——他们只会降低评级。
- “我稍后再写报告。” 复现细节会在几小时内逐渐模糊。
- “这显然是严重级别。” 那就很容易论证。论证清楚。
- “所有问题都标为高危,他们才会认真对待。” 夸大严重程度只会让报告无人问津。
- “我无法完整利用这个漏洞,所以就不写了。” 根据你掌握的证据报告,并说明不确定之处。默不作声更糟。
- “我在代码里发现了它,所以它肯定还存在。” 你读到的可能是过时的代码检出版本。提交报告前,应针对实际发布的版本重新验证——三次提交前就已修复的发现,会让整份报告失去可信度。
- “客户不会喜欢限制说明这一部分。” 如果报告让人以为某个领域已涵盖,而该领域后来发生了泄露,他们会更不喜欢。
- “没有发现问题就说明报告很糟糕。” 覆盖范围诚实且没有发现问题的报告也是有效结果。说明你测试了什么,以及测试得有多深入。
阅读外部来源
以 Markdown 格式获取公开的公告、规范和供应商报告:
curl -sL "https://defuddle.md/<url>" # scheme in the path is optional
这样可以剔除页面上的杂项内容——对于文字页面,令牌数大约减少 78%——并返回全文而非摘要,因此你可以用 grep 搜索,也可以信任未找到结果。
以下三种情况不适用。获取 JSON 和 API 响应时应使用原始内容,因为可读性提取会破坏结构化数据。对于需要身份验证或由 JavaScript 渲染的页面,也应直接获取,因为该工具会以匿名方式检索。并且绝不要通过此工具访问对手基础设施(钓鱼链接、C2、恶意软件托管)、客户拥有的主机或项目 URL——请求会离开你的机器并发送给第三方;对于正在运行的对手基础设施,这还会向运营者发出警报。
有些网站会屏蔽提取器,并返回错误内容而非页面内容——例如 freedesktop.org 返回的 {"error":"Failed to fetch: 418 I'm a teapot"}。这表示获取请求遭到拒绝,并不表示来源称该内容不存在。得出任何结论前,请直接重新获取该 URL。
参考资料
auditing-code-for-vulnerabilities— 审计侧的交付物格式responding-to-incidents— 事件叙述和事后复盘- CVSS 4.0 规范;用于评估漏洞利用可能性的 EPSS;用于分类的 CWE
- ISO/IEC 29147(漏洞披露)和 30111(漏洞处理)