ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Claude Security 报告规范深度解析:CLAUDE-SECURITY-RESULTS.md 的撰写规则与验证流水线

Claude Security 报告规范深度解析:CLAUDE-SECURITY-RESULTS.md 的撰写规则与验证流水线 AI 插件开发工具插件系统【免费下载链接】claude-plugins-officialOfficial, Anthropic-managed directory of high quality Claude Code Plugins.项目地址https://gitcode.com/GitHub_Trending/cl/claude-plugins-official点击查看免费下载Claude Security 插件claude-plugins-official仓库中的 plugins/claude-security每次扫描交付的最终产物是CLAUDE-SECURITY-RESULTS.md——一份写给人类工程师阅读的 Markdown 安全报告。本文基于仓库内的 report-spec.md 完整解读这份报告从结构、字段到写作纪律的全部规范并结合 render_report.py、write_scan_meta.py 与 finding.py 等源码还原报告背后模型叙述、脚本落盘、投票背书的验证流水线。读完你将掌握如何按规范组装一份可被读者快速信任的扫描报告每个 Coverage 字段对应的底层数据来源以及严重性/置信度如何被验证面板钳制。一、报告在交付流水线中的位置唯一由人阅读的散文CLAUDE-SECURITY-RESULTS.md是扫描工作流中唯一以散文形式书写的产物。报告规范开篇就明确了它的读者画像拥有这份代码的工程师很忙会在约九十秒内决定是否对每条 finding 采取行动。因此报告的全部行文纪律都服务于快速、可信、可行动。报告规范同时划清了书写边界render_report.py会从findings.json与votes.json生成机器可读的配套产物——CLAUDE-SECURITY-RESULTS.jsonl每条 finding 一行字段顺序固定、CLAUDE-SECURITY-RESULTS.sarifSARIF 2.1.0 日志以及CLAUDE-SECURITY-REVISION-sha12.json修订戳。规范明确要求不要手写JSONL、SARIF 或 stamp不要在报告里复述JSONL 的内容——本文件是给人读的部分。从源码看这份分工是硬性的。render_report.py 的render()函数会读取运行目录中的scan-meta.json、findings.json、coverage.json、votes.json校验每一条记录然后一次性写出全部机器可读产物stamp 最后写。它甚至要求报告 Markdown 文件必须已存在否则直接拒绝渲染CLAUDE-SECURITY-RESULTS.md is missing. Write the human-readable report before running this script.。verification.status是渲染器从投票记录推导出来的不是由写报告的人声称的——Never claim a verification status the renderer did not print。二、Shape报告的整体骨架报告的 Markdown 结构固定为五部分开篇段落header、## Coverage、## Findings、## What was verified、以及贯穿全程的## Rules纪律规则以 prose 形式存在不单列章节标题。整体模板如下# Claude Security results one paragraph: what was scanned (path, revision, mode, scope), when, at what effort, and the headline: how many findings at what severities, or that there were none. Read revision.dirty in the run dirs scan-meta.json: on true, say the repositorys working tree held uncommitted changes or untracked files -- which ones is not recorded, so never name or explain them; on null, say the tree state could not be determined; otherwise say nothing of it. ## Coverage ... ## Findings ### F1 — title (HIGH, confidence medium) ... ## What was verified ...开篇段落必须一次说清四件事扫了什么路径path、修订revision、模式mode、范围scope何时、以什么 effort低/中/高执行结论头条多少个 finding、分别是什么严重级别或一个都没有。关于revision.dirty的处理有一条非常具体的规则从运行目录的scan-meta.json中读取revision.dirty——为true说明工作树含有未提交更改或未跟踪文件报告必须如实说明但具体是哪些并未被记录绝不能点名或解释为null说明树状态无法确定照实说其他情况保持沉默。这一字段的采集在 write_scan_meta.py 的worktree_dirty()中实现通过git status --porcelain --untracked-filesall判断且会跳过报告目录前缀的路径。扫描时的工作树状态直接影响修订戳文件名-dirty后缀见revision_tag()其目的正是让报告永远与它所描述的代码绑定。三、Coverage让读者可以校准一切的开诚布公Coverage 章节是全报告可信度的根基。规范的原话是This section is what makes the rest of the report trustworthy: a reader who knows what you did not look at can calibrate everything else.一个知道自己没看什么的读者才能校准其余所有内容。这一节必须回答检查了什么、没检查什么、为什么。3.1 稀疏检出sparse checkout如果write_scan_meta.py报告了稀疏检出revision.not_checked_out_dirs保存列表报告必须说明只扫描了检出部分并逐一列出未检出的受跟踪顶层目录。源码中由 write_scan_meta.py 的sparse_checkout()检测core.sparseCheckout配置并记录缺失目录。3.2 验证运行与丢失的候选人Coverage 必须说明面板panel进行了多少次验证运行coverage.verificationRun并点名任何从未被验证的候选人及其原因要么是在通往后续运行的途中丢失coverage.lostCandidates要么被交给了未完成的运行。3.3 未返回的研究员researchers当coverage.researchersReturned低于coverage.researchersDispatched时说明有多少研究员未返回以及他们的阅读成果缺失于本次扫描按coverage.lostResearchers的每条记录以其 reading 命名并引用记录的原因条目超过 10 条时改为按原因分组每组附上研究员被派去读什么描述未返回原因时只允许引用记录的原因报告任何研究覆盖了什么/读了什么的表述包括 What was verified 一节只能计入coverage.returnedReadings中的阅读。3.4 主动跳过的组件coverage.skippedComponents的每条记录都带有被略过的路径和 componentizer 的一行原因vendored、generated、documentation 等。规范强调有意跳过的目录是披露disclosure不是失败——必须写明原因而不是让该区域静默消失。3.5 被修剪的调研镜头pruned buckets如果coverage.prunedBuckets非空每条记录是某组或组件的名称后跟:memory-and-unsafe——即它没有获得的调研镜头research lens。报告必须完整写出每个名字并直白说明该组没有任何研究员被问及内存安全类缺陷无论 tier 如何。关于 change boundary 条目有一条特殊规则它没有对应的coverage.components行因为它不是第二组而是从变更向外工作的研究员对每个变更文件适用同一规则。给出的只能是工作流自身的理由在研究员被简报之前工作流仅凭语言判断changes/commit 扫描看变更文件的扩展名codebase 扫描看 inventory 的语言就认定这些代码全在受托管语言中。不得补充该镜头不适用于此类代码也绝不能把剪枝描述成研究员或面板的决定或因为已有 finding 而放弃镜头。没有条目的组则保留了镜头。3.6 全库扫描的完整性检查整库扫描要求 inventory 覆盖每个顶层目录——要么被扫描要么被显式跳过。coverage.completenessCheckOutcome说明检查是否执行取值含义报告措辞要求checked检查执行且通过说明整个树都有交代partialinventory 把一些顶层目录留在两个账本之外逐一列出coverage.unaccountedTopLevelDirs并直说它们既未被扫描也未被跳过——这正是无 finding会夸大覆盖度的地方not-checkable目录列表未提供、不可读或为空而 inventory 却命名了子目录coverage.topLevelRejected说明直说完整性无法检查——这是把无 finding从未检查变成干净的关键not-applicablediff/commit/范围扫描目标是变更或范围或低 effort 且无 inventory 的运行无需多言3.7 inventory 回退fallback若coverage.inventoryFallback被设置说明 inventory 的分区未被使用整棵树被当作一个组件阅读完整但更粗粒度。原因三选一incomplete-partition其答案会认可它从未命名的覆盖跳过了整个目标或只有爬出树的路径拒绝项列在coverage.inventoryRejectedinventory-failed它没有作答empty-partition它答了个空。3.8 changes / commit 扫描的特殊规则对 changes 或 commit 扫描报告要说审查的是变更而非仓库用平实语言命名变更遵循jobs/scan-changes.md中关于提交数与分支的规则而不是用coverage.range里的提交 id按组列出变更文件coverage.componentshelper 统计的coverage.changedFileCount个文件中的coverage.diffFiles个、coverage.diffLines行报告派出多少研究员、返回多少coverage.researchersDispatched/coverage.researchersReturned以及被要求投入的 effortcoverage.researchEffort——是被要求而非实测模型运行时可能自行调整明确声明变更未参与其中的缺陷不属于本次审查范围留给 codebase 扫描列出coverage.preExisting的每条记录面板判定为真实但早于变更的候选人当基线是分支自身的已推送副本diff 只含未推送提交时说明已推送提交不在此次审查内coverage.outsideScope非空时说明这些 finding它命名了它们在请求范围之外因变更触及它们而报告coverage.changedFilesRejected被设置时引用记录的值说明变更被作为一个组审查、其研究员自行列出了文件若coverage.changedFilesMiscounted也被设置给出两个数字、说明审查了哪个列表其reviewed字段以及那是多少文件coverage.diffFiles。3.9 折叠形状与范围大小被拒coverage.collapsed为small-scope说明中等 effort 的小范围给出coverage.scopeFiles折叠成了成比例的单研究员形态——一次快速定向扫描仍经面板验证但不是穷尽阅读coverage.scopeSizeRejected引用记录值说明其对实际运行 tier 的后果——medium 下范围未被当作小范围处理因此跑的是完整流水线而非快速路径且空范围无法被短路。3.10 运行规模的报告当coverage.targetComponents被设置时说明运行如何被定大小目标约有coverage.targetFiles个受跟踪文件、约coverage.targetComponents个组件每个约coverage.filesPerComponent个文件或当目标持有的组件数超过coverage.componentCap时更大最多保留coverage.componentCap个。3.11 研究员自己的未读声明与对照账最后报告要转述研究员自己报告没读过的东西——作为他们的陈述而非事实coverage.research.components按组件列出其研究员声明未触及的路径及原因——按目录归纳成一行背景树——vendored 树、焦点下的测试与 fixture 树被留作背景——是预期中的背景而非缺口单个文件只在每组件少量时点名coverage.research.tree存在时把该陈述与组件内受跟踪文件对照——多少文件读到了结论、多少位于声明未触及的路径下、多少没有任何研究员交代coverage.research.capped为 true 时账目被截断即至少读了这么多、至多有这么多未交代——并列出coverage.research.tree.unaccountedPaths列前几个总数是全部因为一个没人读完的组件绝不能冒充干净的组件所有组件之外的文件outsideComponents是本小节已点名的跳过/丢弃区域加上无组件认领的根文件不是研究员的缺口当coverage.research为 null 或缺少 tree 时该检查未运行对此只字不提但已声明的路径仍然成立。这些数据在渲染器里被整理成run_shaperender_report.py并同步反映到 SARIF 的通知notifications中。四、Findings每条发现的八段式模板## Findings章节中每条 finding 的标题里的Fn是它在findings.json中的id逐字照抄——finding 到达时已处于报告顺序因此绝不重新编号、不重排、不发明 id。编号中的缺口是面板未在该 id 下保留的候选人只有当完整面板驳斥它时才可称其为被拒绝不能因为coverage.adversarialCasualties、coverage.preExisting或coverage.lostCandidates按候选人 id点名它就那样说。每条 finding 的模板### F1 — title (HIGH, confidence medium) **Impact.** what an attacker gets. Lead with this: it is what decides priority. **Where.** path/to/file.py:123 in function_name — cwe_id, then (also other_cwe_ids) when the finding carries further CWEs **Link to the change.** a changes or commit scan only: the findings via_change, the changed line that takes part in the attack and how, named by file:line and never quoted; omit the line for a scan of the codebase **What.** the vulnerability, in two or three sentences. Name the untrusted source, the dangerous operation, and why nothing in between stops it. **Exploit scenario.** a concrete walk-through. Not an attacker could inject SQL -- what they send, what happens, what they get. **Preconditions.** bullets: what must be true. Authentication? A non-default config? Victim interaction? An empty list means none, which is worth saying. **Fix.** what to change, in outcome terms. The root cause at the sink, not a patch at one caller. **Verification.** n/3 lens verifiers confirmed.各字段的写作要求Impact攻击者能得到什么。必须放在最前——它决定优先级Where文件:行加函数名后跟主 CWE id携带更多 CWE 时追加(also other_cwe_ids)Link to the change仅 changes/commit 扫描使用取 finding 的via_change点名参与攻击的变更行及其方式以file:line命名从不引用原文codebase 扫描省略此行。从 finding.py 可见via_change以file:line开头、由LINK_SITE正则识别并规范化What两到三句话说明漏洞——点出不受信任的来源、危险操作以及中间为什么没有任何东西阻止它Exploit scenario具体走一遍——不是攻击者可注入 SQL而是他们发送什么、发生什么、得到什么Preconditions必须为真的条件列表认证非默认配置受害者交互——空列表意味着无前置条件这一点值得明说Fix以结果导向说明改什么——针对 sink 处的根因而非某个调用点的补丁Verificationn/3个镜头验证者确认。F2 — ...依此类推。验证者计数对应源码中的固定面板规模PANEL_VOTER_COUNT 3、PANEL_KEEP_QUORUM 2见 finding.py即每条 finding 由三名验证者组成的对抗性面板审查、2/3 通过才保留。五、What was verified验证状态必须如实交代## What was verified用一段话说明产出这些 finding 的流水线、每条 finding 通过的投票、以及 stamp 的verification.status。状态不是verified时用平实语言解释其含义和应对措施不得掩盖状态是verified但存在未返回的研究员时说明verified不覆盖缺失的阅读。verification.status的推导逻辑在 render_report.py 的verification_summary()中它只会在每一项都满足时给出verified否则给出unverified并附带机器可读的reason_kind。源码中可见的失败原因种类包括reason_kind触发条件no-vote-record运行目录没有 votes.json 或它不是扫描工作流的记录no-candidate-countvotes.json 缺candidates字段nothing-examined派出了研究员但一个都没返回finding-panel-incomplete有 finding 缺少完整 3 票面板轮次finding-below-quorum报告的 finding 中有未达保留法定人数的candidates-not-paneled记录了候选人但无一入面板no-panel-completed派发了面板轮次但无一完成完整 3 票审查candidate-panel-incomplete有候选人未经完整面板轮次即被丢弃continuation-incomplete有候选人被交给未完成的验证运行findings-refused渲染时被拒绝的 finding 缺席报告这套枚举证明了一个关键设计报告对自己严谨程度的说明是由代码计算出来的而非产生 finding 的模型所声称的README 中亦明示the record of how thoroughly a run was verified is computed in code rather than asserted by the model that produced the findings。六、Rules贯穿全篇的写作纪律6.1 严重性是可利用性与影响不是置信度CRITICAL严重影响且攻击者面前毫无阻碍HIGH严重影响但存在一个真实障碍MEDIUM影响有界或严重影响但需多个条件LOW影响有限且利用苛刻。findings.json中的严重性是最终裁决当面板的确认投票者将 finding 评为低于研究员所评的级别时工作流已将其调低coverage.severityLowered会点名每条此类 finding 并给出两个评级——报告必须在它的Verification.行说明这一点不得恢复被调低的严重性。不确定性与confidence无关而是置信度词low、medium、high由面板投票钳制——只有全票通过的面板才配得上high工作流已把其他任何high调低若报告者擅自提高render_report.py会再把它降回来。这一钳制在源码vote_confidence_ceiling()finding.py中有精确对应面板完整时只有true PANEL_VOTER_COUNT全票才是high否则是medium。6.2 排序与分批先按严重性、再按置信度排序——读者会中途停下把最重要的放最上面超过二十条 finding 分批写一次调用容纳全部 finding 可能超出模型输出上限被截断的 Write 会被整体拒绝。因此第一个 Write 包含开篇段落、Coverage、前二十条 finding 和 What was verified之后每二十条用 Edit 插入到## What was verified标题之前。6.3 每个 finding 必须引用真实的 file:line指向错误行的 finding 比漏报更伤人——读者在追查时会失去对报告其余部分的信任。渲染器为此做了路径校验file_field()/relative_path()会拒绝任何逃出仓库或指向缺失文件的路径finding.py无法承载路径的 finding 会被点名拒绝refused id并从产物中剔除stamp 相应标记为未验证。6.4 硬编码凭据 finding 的特殊规则任何携带 CWE-798、CWE-259、CWE-321 或 CWE-671在cwe_id或other_cwe_ids中的 finding不写 Link to the change 行——它本要点名的变更行就是凭据本身而 JSONL 和 SARIF 已经收回了该链接。README 中亦说明凭据 finding 的文件、行号与符号仍会定位但绝不引用凭据所在源码行。6.5 无控制字符只允许\n和\t。报告在终端中被阅读转义序列可能改写人所见的内容。若扫描源码中确实出现此类字节描述它而非复现它。6.6 不模糊、不填充不要为了对代码客气而软化真实 finding也不要为了显得周全而夸大细枝末节。No findings 本身就是一份完整的报告——把它写好覆盖了什么、没覆盖什么比一整页可能更有价值。6.7 研究者的镜头不是面板的研究者的镜头lens是一个漏洞类别其组保留的类别之一或全部面板投票者的镜头是可达性reachability、影响impact或防御defenses。绝不可把面板的三个当作研究者的三个。6.8 从不声称运行过什么扫描不执行仓库代码没有运行过测试、没有发射过 exploit、没有验证过 PoC。每条 finding 都源自阅读。报告必须这样说而不是暗示一次演示。这与插件整体的信任模型一致——仓库内容是被审查的数据永不是指令。七、写作质量的标杆Example of the bar规范用一个对照展示了合格与不合格的 finding 写法。不要这样写The code may be vulnerable to SQL injection. Consider using parameterized queries as a best practice.要这样写Impact.Any unauthenticated caller ofGET /users?namecan read every row of theuserstable, including password hashes and email addresses.Where.api/app.py:3inget_user— CWE-89What.namearrives from the query string inhandlers.py:41and is interpolated into the SQL string with%. No escaping or validation runs on the path between them; thevalidate_namecall inhandlers.py:38checks length only.Exploit scenario.GET /users?name OR 11makes the WHERE clause tautological and returns the full table in the JSON response.对比可见合格示例把可能、请考虑的模糊建议替换为可验证的具体事实链——来源handlers.py:41的 query string、危险操作%插值、缺失的防线validate_name只查长度、以及一条可复现的 exploit 路径。八、从规范到实现报告背后的验证闭环将 report-spec 与仓库源码对照可以还原出整条验证闭环扫描元数据write_scan_meta.py从 git 自身捕获修订commit、branch、dirty 状态、顶层目录、文件计数写入scan-meta.json——stamp 绝不依赖任何人转写的值write_scan_meta.py研究工作流claude-security:scanworkflow 派出研究员并按 tier 组织low 单研究员、medium 组件×类别、high 双研究员最终一律进入固定的三票验证面板投票记录面板的投票进入votes.jsonverification_summary()据此计算状态与各计数render_report.py去重与落盘one_per_site()把同一 site规则×文件×行的多个 finding 合并为最强一条其余在产物中披露合并句render_report.pySARIF/JSONL/stamp 全部由脚本写出清洗与交付交付后scan-redactor把产物中的凭据值替换为[REDACTED]这是模型的最佳努力而非保证随后运行目录被整体移除报告目录只留下用户阅读的产物。这套设计在 patch-spec.md 中形成了对称结构修复工作同样由人写工作记录patches.json、脚本渲染产物Fn.patch等no diff byte and no confidence claim is ever re-typed by a model on its way to the user没有任何 diff 字节或置信度声明在通往用户的路上被模型重新转写。报告规范与补丁规范共同构成了 Claude Security 插件的契约层模型叙述与决策脚本落盘与验证人类阅读与行动。对于阅读或维护此类报告的开发者而言最值得带走的三条原则是报告的可信度取决于它如何交代没看什么Coverage每条 finding 的优先级由 Impact 与可复现的 Exploit scenario 决定而不是措辞的轻重而这份报告有多可靠这件事永远以render_report.py盖下的verification.status为准。赞分享AI 插件开发工具插件系统【免费下载链接】claude-plugins-officialOfficial, Anthropic-managed directory of high quality Claude Code Plugins.项目地址https://gitcode.com/GitHub_Trending/cl/claude-plugins-official点击查看免费下载相关推荐security-audit skill 验证与报告流水线深度解析从候选漏洞到机器可读的 findings.json 与审计报告security audit skill 验证与报告流水线深度解析从候选漏洞到机器可读的 findings.json 与审计报告 本篇技术指南围绕 VALIDAI 技能应用安全Claude Code Haha 文档编写规范docs/AGENTS.md 全解与站点流水线实践Claude Code Haha 文档编写规范docs/AGENTS.md 全解与站点流水线实践 导读本文面向在 Claude Code Haha 仓库中新人工智能AI 应用桌面应用代码智能体MCP Clientswewe-rss微信公众号RSS生成完整指南wewe rss微信公众号RSS生成完整指南 微信公众号文章藏在微信的会话列表里既导不进 RSS 阅读器也没有全文输出。wewe rss 是一个可私有化部署AI 插件开发工具插件系统上一篇CAP 消息序列化机制详解从默认 JSON 到自定义 ISerializer 扩展下一篇显卡驱动残留清不净DDU 显卡驱动清理彻底卸载一次搞定创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表