关于 evidence-hygiene
面向漏洞赏金研究人员的 PoC 证据整理技能,指导截图、HAR 和请求记录中的敏感信息处理。重点区分需遮盖的凭据与个人信息,以及有助于复现的元数据。
主要功能
- 01识别会话凭据与其他敏感信息
- 02指导截图和 HAR 文件脱敏
- 03区分需遮盖与应保留的证据
- 04提供 Burp Suite 和 DevTools 取证建议
- 05规范 PoC 截图顺序与内容
适用场景
- 01提交漏洞报告前清理 HAR 文件
- 02制作证明跨账户影响的截图
- 03记录状态变更漏洞的验证过程
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ uphiago/ recon-skills --skill evidence-hygiene安装后在 Claude Code 中输入/evidence-hygiene确认已加载。
详细介绍
证据卫生——PoC 捕获与脱敏规范
在捕获任何屏幕截图、导出任何 HAR,或将任何证据附加到漏洞赏金提交内容之前,请使用此技能。它可以避免最常见的证据卫生错误,防止 Cookie 泄露、未经同意分享个人身份信息(PII),或截图不适合用于分诊。
核心原则:漏洞赏金证据旨在说服分诊人员。除此之外的任何内容——有效 Cookie、真实用户的 PII、无用的内部跟踪 ID——都不应出现在证据中。
1. 两类敏感数据
每份 PoC 产物(截图、HAR、原始 HTTP 请求、终端记录)都可能包含需要区别处理的数据。
| 类别 | 示例 | 处理方式 |
|---|---|---|
| 你账户的机密信息 | 会话 Cookie、OAuth 令牌、刷新令牌、API 密钥 | 始终脱敏。即使是在私密漏洞赏金平台的附件中也不例外。账户和会话都属于你——请妥善保护。 |
| 其他用户的 PII | 真实姓名、电子邮件、电话号码、地址、个人资料照片、账户 ID | 除非需要明确展示跨账户影响,否则应脱敏。即使需要展示,也要遮挡面部并尽量减少显示的数据。 |
| 对分诊有用的元数据 | 跟踪 ID(x-datadog-trace-id)、请求 ID、服务器时间戳、你的测试账户 UID/电子邮件、GraphQL 操作名称、响应结构 | 保持可见——这些信息有助于分诊人员关联日志并复现问题。 |
| 测试账户密码(有限使用) | 测试账户的一次性密码(例如 Testing@5678) | 如果在提交后立即更换,这类密码可以出现在截图中,这样截图中显示的密码就会失效。不要在证据中保留日常使用的真实密码。 |
2. Cookie 脱敏规范
2.1 必须遮挡的内容
会话 Cookie 值是任何 PoC 中价值最高的机密信息。请遮挡:
- 会话 Cookie(
authn、session、sid、__Secure-id等,名称因目标而异) - 与你的会话绑定的
csrf-token Authorization标头(Bearer 令牌、JWT)- 任何携带会话信息的 Cookie 的
Cookie请求标头值 - 任何携带会话信息的 Cookie 的
Set-Cookie响应标头值
2.2 可以安全保留可见的内容
- Cloudflare Cookie(
__cf_bm、_cfuvid)——这些用于机器人管理,不携带会话信息 - 分析 Cookie(
ajs_anonymous_id、_ga) - 跟踪关联 ID(
x-datadog-trace-id、x-request-id) - 服务器/框架标头(
Server: cloudflare、X-Frame-Options) - 你的测试账户电子邮件/UID(参见
bugcrowd-reporting中的 Bugcrowdninja 别名部分)
2.3 脱敏方法(按实用性排序)
方法 A——一开始就不要捕获 Cookie(可行时优先采用)
- 对于 DevTools Console PoC:使用
credentials: 'include',让浏览器自动发送 Cookie。Console 输出不会回显 Cookie。请截取 Console 输出,绝不要截取 Network 标签页中的 Headers 面板。 - 对于 Burp Repeater PoC:截图前,将底部请求/响应面板的分隔线向下拖动,以隐藏请求正文。运行 Intruder 时,只截取 Results 表格。
方法 B——在图像编辑器中添加黑条(捕获内容不可避免地包含 Cookie 时)
- macOS:在 Preview 中打开截图 → Tools → Annotate → Rectangle → 将填充颜色设为黑色 → 在 Cookie 值上拖动矩形 → 保存
- Windows:使用 Snip & Sketch 的标注工具或任何图像编辑器(Paint.NET 等)
- Burp 本身:在 Burp 的 Proxy → Match and Replace 中,你可以在截图前预先将 Cookie 值脱敏为占位字符串
方法 C——在原始文本中查找并替换(适用于 HAR 文件、终端记录)
- jq 命令参见 §4
2.4 截图前检查清单
点击 Capture 前:
[ ] Network tab Headers panel is collapsed or out of frame
[ ] Burp's Request panel is hidden behind the divider drag
[ ] No "Copy as cURL" output is visible on screen
[ ] DevTools Application → Storage → Cookies tab is closed
[ ] Browser URL bar doesn't show a session token in query string (rare but possible)
截图后:
[ ] Open the screenshot at full resolution before saving
[ ] Search for the session cookie name substring in any visible text — if present, redact
[ ] Search for the literal first 6 chars of your cookie value — if present, redact
[ ] Compare to the previous PoC screenshot in the same engagement — same redaction discipline
3. PII 黑条规范
如果 PoC 不可避免地会暴露其他用户的数据(例如,通过展示攻击者会话响应中的受害者电子邮件来证明 IDOR),即使在私密附件中,也要将实际 PII 脱敏。
3.1 需要遮盖的内容(其他用户的数据)
- 名字、姓氏(全部或部分)
- 电子邮件地址(遮盖本地部分;如果域名不会泄露身份,可以保留)
- 电话号码(遮盖最后 7 位,可选择保留国家代码)
- 住址(遮盖城市以下的所有信息)
- 出生日期(遮盖年份,可选择遮盖月份)
- 政府签发的证件号码(SSN、护照号码——全部遮盖)
- 个人资料照片/人脸图像(用黑条完全遮挡人脸)
- 用户可能会将其与公开资料关联起来的账户 ID
3.2 应保留可见的内容(用于证明漏洞,而非识别用户)
- 字段确实被返回这一事实(JSON 键名)
- 字段的结构/类型(
"first_name": "<REDACTED>") - 你自己的(攻击者会话的)UID/电子邮件——用于证明跨账户访问
- 端点 URL 和请求方法
- 跟踪 ID
3.3 示例——IDOR PoC 请求体
不妥(泄露受害者的完整 PII):
{"data":{"contact":{"first_name":"Nadene","last_name":"Afton","email":"[email protected]","phone":"+1-555-867-5309"}}}
妥当(证明漏洞,同时遮盖 PII):
{"data":{"contact":{"first_name":"<REDACTED — real first name>","last_name":"<REDACTED — real last name>","email":"<REDACTED>@example.com","phone":"<REDACTED>"}}}
如果使用截图,请为每个值添加矩形标注并用黑条遮挡;空间允许时,标注文字为“REAL PII REDACTED”。
3.4 报告正文中
明确说明已进行遮盖:
## Proof of Concept
The screenshot below demonstrates the IDOR. The attacker session (uid 12345678) successfully retrieves the victim's profile data (uid 99887766). **Real PII fields in the response are masked with black rectangles to limit unauthorized exposure of victim data, per responsible-disclosure hygiene.** The unredacted response is available privately on request.
这能让分诊人员知道你处理得很谨慎;如果他们需要未遮盖版本进行验证,也能清楚了解如何获取。
4. HAR 文件清理
HAR(HTTP Archive)文件是网络流量的 JSON 转储,包含完整的请求/响应正文和标头。其中包括 Cookie、身份验证令牌,以及传输过程中的任何 PII。
4.1 生成 HAR
Chrome DevTools → Network 标签页 → 在请求列表任意位置单击右键 → “Save all as HAR with content”
4.2 附加前进行清理
使用 jq 移除敏感标头。将其保存为 Shell 函数或可重复使用的单行命令:
sanitize_har() {
local input="$1"
local output="${1%.har}.sanitized.har"
jq '
.log.entries |= map(
(.request.headers |= map(
if .name | ascii_downcase | IN("cookie", "authorization", "x-csrf-token") then .value = "<REDACTED>" else . end
)) |
(.response.headers |= map(
if .name | ascii_downcase | IN("set-cookie") then .value = "<REDACTED>" else . end
)) |
(.request.cookies |= map(.value = "<REDACTED>")) |
(.response.cookies |= map(.value = "<REDACTED>"))
)
' "$input" > "$output"
echo "Sanitized: $output"
}
用法:
sanitize_har /path/to/exported.har
# Output: /path/to/exported.sanitized.har
4.3 附加前进行验证
# Check that no Cookie or Authorization values are leaking
grep -i 'authn\|"cookie"\|authorization' /path/to/exported.sanitized.har | head -20
如果输出中出现了真实 Cookie 值,说明清理时遗漏了内容——请针对该字段名修正 jq 过滤器。
4.4 移除其他用户的 PII(如适用)
如果 HAR 捕获了跨账户数据(例如在 IDOR 演示期间),还应移除响应正文中包含受害者 PII 的字段。将以下内容添加到 jq 过滤器:
(.response.content.text |= (
if . then
(fromjson? // .) | tostring | gsub("real.first.name.example"; "<REDACTED>")
else . end
))
请根据实际捕获的数据自定义 gsub 匹配模式。
5. Burp Suite 截图规范
5.1 Repeater(单个请求演示)
- 在 Repeater 请求面板中,Cookie 标头单独占一行——将面板分隔线向下拖动,隐藏请求行/目标行以下的所有内容
- 或者:截图前,临时从 Repeater 面板中删除 Cookie 标头文本(不会影响原始捕获的请求),然后再恢复
- 仅截取响应面板(右侧),显示用于证明漏洞的 JSON/HTML 响应
5.2 Intruder 结果表(速率限制/暴力破解演示)
结果窗口是速率限制问题最有力的证据。要清晰地截取:
- 攻击完成后,将结果表与请求/响应面板之间的水平分隔线向下拖动,直到只显示结果表
- 截图仅包含以下列:
Request#、Payload、Status code、Response received、Length - 不要包含请求/响应子面板——其中包含 Cookie
5.3 Proxy HTTP 历史记录(捕获演示)
几乎从来都不适合用作截图——它会显示完整的请求/响应对,其中包含 Cookie。演示时请改用 Repeater。
5.4 Scanner 发现项(如适用)
Scanner 标签页的 Issues 面板通常可以安全截图——其中显示发现项摘要,不包含底层请求正文。只有在先遮盖特定发现项的证据后,才点击进入该发现项并截图。
6. Chrome DevTools 控制台 PoC 模式
6.1 简洁 PoC 模式
fetch('/api/endpoint', {
method: 'POST',
headers: {'content-type': 'application/json'},
credentials: 'include', // sends cookies automatically — they won't appear in your code
body: JSON.stringify({ /* your payload */ })
}).then(r => r.json()).then(j => console.log("LABEL:", JSON.stringify(j)))
这样做更简洁的原因:
credentials: 'include'表示浏览器会发送 Cookie。代码不会引用它们,它们也不会出现在截图中。console.log("LABEL:", ...)会输出带标签的行,方便你在截图中查找JSON.stringify(j)会将响应格式化为单行,便于精确裁剪
6.2 多步骤 PoC(每次调用之间清空控制台)
对于 4 步 PoC(变更前验证 / 变更 / 变更后验证 / 还原),请在每次调用之间清空控制台,确保每张截图只显示一次调用和一个响应:
- Mac:
Cmd+K - Windows / Linux:
Ctrl+L
响应打印后立即截图,不要等待无关的框架警告出现。
6.3 长响应(截断后截图)
如果响应正文太长,无法清晰截图,请改为记录摘要:
fetch('/api/endpoint', { /* ... */ })
.then(r => r.json())
.then(j => {
console.log("RESPONSE SHAPE:", Object.keys(j.data || {}));
console.log("CRITICAL FIELD:", j.data?.victim_id, j.data?.email);
// (Don't dump the full j — your screenshot becomes unreadable)
})
6.4 粘贴许可提醒
Chrome 会将禁止粘贴到 DevTools 控制台作为防范自我 XSS 的措施。在每个会话开始时输入一次 allow pasting(原样输入该短语)。请在拍摄任何“运行中的 PoC”截图之前完成此操作,否则警告文本会出现在截图中。
7. 截图顺序规范
7.1 5 步 PoC 模式(适用于状态变更类发现)
对于“无需再次验证即可更改密码”这类发现,标准的 5 张截图模式如下:
- 变更前状态验证 —
verify_password("current") → true。证明你知道初始状态。 - 漏洞本身 —
update_password(...)无需再次验证即可成功。这是最重要的一张截图。 - 变更后状态验证(否定) —
verify_password("old") → false。证明变更已生效。 - 变更后状态验证(肯定) —
verify_password("new") → true。证明新凭据已生效。 - 带外副作用 — 收件箱截图,显示是否收到通知邮件。证明是否存在被动防御。
7.2 文件名规范
使用编号、描述性名称,并以连字符分隔:
{finding-#}-step{step-#}-{description}.png
Examples:
04-step1-verify-true-before.png
04-step2-update-password-no-stepup.png
04-step3-verify-false-after.png
04-step4-verify-true-new-pw.png
04-step5-inbox-notification-check.png
在报告正文中,通过文件名引用每张截图:
- **Screenshot 1 (`04-step1-verify-true-before.png`)** — verify_password returns true with the current password.
- **Screenshot 2 (`04-step2-update-password-no-stepup.png`)** — update_password returns User with no StepUpRequiredError. THIS IS THE BUG.
- **Screenshot 3 (`04-step3-verify-false-after.png`)** — verify_password with old password returns false.
- **Screenshot 4 (`04-step4-verify-true-new-pw.png`)** — verify_password with new password returns true.
- **Screenshot 5 (`04-step5-inbox-notification-check.png`)** — inbox showing whether out-of-band notification was sent.
7.3 截图时机
- 所有截图应在同一次操作中完成,不要分多次会话拍摄。会话中途出现的不一致(浏览器尺寸不同、Cookie 值不同)会让审核人员感到困惑。
- 如果可以避免,请不要在截图之间重新加载页面。重新加载会重新生成 Cookie,并可能导致先前的截图失效。
面向公众的输出脱敏(OPSEC)
向公开渠道发布任何输出时(GitHub README、博客文章、报告、共享仪表板):
规则 — 绝不包含:
- 公司 / 域名及具体漏洞详情。
- 人员姓名(员工、用户、研究人员)
- 真实人员的电子邮件地址
- 内部 IP、主机名或 AD 域
- 原始凭据(即使已过期)
安全替代方案:
- 将公司名称替换为行业类别或中性目标标签。
- 将具体数量替换为范围:使用
several users,而不是11 users - 描述可复用的模式,不包含项目标识信息。
- 使用通用表格:
| Critical | 8 | MySQL exposed, PHPInfo + exec |,不要点名具体目标
公开发布前检查清单:
[ ] Scanned for hardcoded domain names (grep -E '[a-z]+\\.(com|io|app)' *.md)
[ ] Scanned for email addresses (grep -E '[a-zA-Z.+-]+@[a-zA-Z-]+\\.[a-zA-Z.]+' *.md)
[ ] Scanned for internal IPs (grep -E '10\\.|172\\.1[6-9]\\.|192\\.168\\.' *.md)
[ ] Confirmed no person names in output
[ ] Confirmed vuln descriptions are pattern-based, not target-based
现实后果:
在发布漏洞信息时同时披露目标名称,会泄露项目数据。 基于模式的描述既能保留可复用的经验,又不会暴露目标。
提交后的安全整理
在漏洞赏金平台上点击 Submit 后:
8.1 轮换测试账户凭据
1. Log out of the target
2. Log back in (this rotates the session cookie — any cookie shown in your screenshots is now dead)
3. Change the password to a fresh value not used elsewhere (any password shown in your screenshots is now dead)
8.2 私下保存未脱敏材料
将未脱敏的 HAR 文件 / 截图保存在只有你能访问的本地文件夹中。审核人员可能会在验证期间要求查看未脱敏版本。绝不要通过电子邮件分享未脱敏材料——请使用现有提交主题中的平台私密附件系统。
8.3 不要公开谈论发现
大多数平台的保密要求同时适用于尚未解决和已解决的问题。在项目明确允许之前,不要发布推文、写博客或在任何论坛讨论该发现。
8.4 审查本地文件
每季度检查一次 ~/security-research/ 和 ~/Downloads/,清理旧项目留下的过期 HAR 文件和屏幕截图。将其移至妥善加密的归档,或直接删除。漏洞赏金项目的文件很敏感——它们很快就会积累起来,并成为负担。
陷阱
- 在屏幕截图中捕获 Cookie — 这是证据卫生方面最常见的错误。务必折叠 Network 标签页中的 Headers 面板,隐藏 Burp 的 Request 面板,绝不要截取“Copy as cURL”输出。
- 未遮盖受害者的 PII — 显示真实姓名、电子邮件地址和电话号码的 IDOR PoC 违反负责任披露原则。即使是在平台私密附件中,也要用黑条遮盖其他用户的 PII。
- 包含有效 Cookie 的 HAR 文件 — 导出的 HAR 文件中含有完整 Cookie 值,除非使用 jq 进行清理。添加附件前务必运行 sanitize_har 函数。
- Console.log 回显 Cookie — DevTools Console PoC 必须使用
credentials: 'include',绝不要在 fetch 调用中硬编码 Cookie 值。 - 忘记输入“allow pasting” — Chrome 默认会阻止向 Console 粘贴内容。在任何 PoC 之前输入
allow pasting,以免警告文字出现在屏幕截图中。 - 步骤之间未清空 Console — 输出相互重叠的多步骤 PoC 会让分诊人员困惑。每次调用之间都要清空 Console(Cmd+K / Ctrl+L)。
- 截取 Proxy HTTP history — 其中会显示包含 Cookie 的完整请求和响应。改用 Repeater,并隐藏请求面板。
- 提交后未轮换 Cookie — 提交的屏幕截图中可见的 Cookie,只有在注销并重新登录、完成轮换后才会失效。提交后立即轮换。
- 屏幕截图尺寸不一致 — PoC 各步骤使用不同的浏览器尺寸会显得不专业。所有屏幕截图都应在同一次操作中以一致的窗口尺寸截取。
- 未保存未遮盖的原始版本 — 分诊人员可能会要求查看未遮盖的版本。将原始文件保存在本地加密文件夹中;绝不要通过电子邮件分享。
- 公开输出中包含真实域名 — 任何包含“target.example.com — 漏洞详情”的 README、博客或报告都会暴露客户端身份。使用行业标签和基于模式的描述。
- 过期文件不断累积 — 旧项目的 HAR 文件和屏幕截图会越积越多。每季度审查一次:归档或删除过期的证据文件。
9. 与其他技能配合使用
| 对于此问题 / 任务 | 使用此技能 |
|---|---|
| “我到底应不应该报告这个发现?” | triage-validation |
| “报告正文模板是什么?” | report-writing |
| “Bugcrowd 的 VRT / 严重性 / OOS 反驳怎么写?” | bugcrowd-reporting |
| “如何遮盖 / 清理这些证据?” | 此技能(evidence-hygiene) |
| “如何证明漏洞确实会触发?” | security-arsenal |
| “这个资产类别的侦察探测方法在哪里?” | offensive-osint |
验证
运行此自测,确认已做好证据卫生方面的准备:
-
HAR 清理器语法 — 验证 jq 过滤器的语法是否有效:
echo '{"log":{"entries":[{"request":{"headers":[{"name":"Cookie","value":"secret=abc123"}],"cookies":[{"value":"abc123"}]}}]}}' | jq '.log.entries |= map((.request.headers |= map(if .name | ascii_downcase | IN("cookie","authorization") then .value = "<REDACTED>" else . end)) | (.request.cookies |= map(.value = "<REDACTED>")))' >/dev/null 2>&1 && echo "PASS: jq filter valid" || echo "FAIL" -
Cookie 遮盖清单 — 确认存在屏幕截图前检查清单:
grep -q "Pre-screenshot checklist" SKILL.md && echo "PASS" || echo "FAIL" grep -q "Network tab Headers panel is collapsed" SKILL.md && echo "PASS" || echo "FAIL" -
PII 黑条处理规范 — 确认已记录 PII 遮盖流程:
grep -q "PII Black-Bar" SKILL.md && echo "PASS" || echo "FAIL" grep -q "real names, emails, phone numbers" SKILL.md && echo "PASS" || echo "FAIL" -
Console PoC 模式 — 确认存在干净的 fetch 模式:
grep -q "credentials: .include." SKILL.md && echo "PASS: credentials:include pattern" || echo "FAIL" grep -q "allow pasting" SKILL.md && echo "PASS: allow-pasting reminder" || echo "FAIL" -
提交后卫生措施 — 确认存在轮换流程:
grep -q "Rotate the test account credentials" SKILL.md && echo "PASS" || echo "FAIL"
全部 5 项测试均会验证关键的证据卫生保护措施是否到位。
使用说明
准备提交内容时,本技能应与 report-writing 一起加载;如果是 Bugcrowd,还应同时加载 bugcrowd-reporting。本技能不涵盖:
- 要捕获什么(这是
triage-validation和report-writing的工作——它们会告诉你报告需要哪些证据才能被接受) - 如何展示漏洞利用过程(这是
security-arsenal的工作——提供要发送的有效载荷) - 在哪里查找目标资产(这是
offensive-osint的工作——侦察)
本技能只涵盖从“我有证据”到“我将证据附加到平台”之间的脱敏、清理和规范处理环节。
相关技能与流程链
report-writing— 证据完成脱敏并可用于报告正文时使用。工作流基元:脱敏通过截图前检查清单后,交由report-writing生成适用于特定平台的报告模板(H1 / Bugcrowd / Intigriti / Immunefi)。bugcrowd-reporting— 脱敏后的证据专门用于 Bugcrowd 时使用。工作流基元:脱敏后的截图和已清理的 HAR 文件将作为附件,在bugcrowd-reporting的 VRT 映射提交正文中引用。triage-validation— 确定是否需要证据以及需要哪些证据时使用。工作流基元:triage-validation会说明“密码更改时无需额外验证的漏洞需要一份包含 5 张截图的 PoC”;本技能会说明“如何干净地捕获并脱敏这 5 张截图”。security-arsenal— 记录生成证据的有效载荷时使用。工作流基元:有效载荷(来自security-arsenal)原样放入报告;其输出/响应(由本技能处理)在截图前对 Cookie 和个人身份信息进行脱敏。bb-methodology— 第 5 阶段(验证与报告)需要捕获证据时使用。工作流基元:第 5 阶段的证据捕获步骤会先经过本技能处理,再起草报告。