Skip to content

fix: 修复隐私访问与账本校验漏洞 - #17

Open
AuroraNest wants to merge 2 commits into
mxx1111:mainfrom
AuroraNest:Aurora/security-hardening
Open

fix: 修复隐私访问与账本校验漏洞#17
AuroraNest wants to merge 2 commits into
mxx1111:mainfrom
AuroraNest:Aurora/security-hardening

Conversation

@AuroraNest

@AuroraNest AuroraNest commented Aug 19, 2026

Copy link
Copy Markdown

背景

仓库安全审计确认 6 个高置信度问题,涉及 P2 私有源码边界、托管退款归属、结算凭据真实性、特殊文件名扫描、过宽白名单和 GitHub metadata 覆盖.

改动

  • 将 P2 更正为可复制源码的临时受信访问,明确撤权无法收回已有副本.
  • 将 refund 绑定到原始 escrow 出资人.
  • 校验 settle 使用的 GitHub PR URL、任务关联及 mergedAt 或已接受 closedAt.
  • 使用 NUL framing 读取 tracked filenames,读取失败时 fail closed,并转义 GitHub Actions annotations.
  • allowlist 仅允许精确到具体行的 exemption.
  • 覆盖 Issue title、PR title 和 PR body 的凭据扫描.

影响范围

现有 18 条 ledger entries 和余额保持不变. 6 个历史 settlement PR 均通过 GitHub API 实证校验. 没有新增第三方依赖.

验证

  • npm test: 50 passed.
  • npm run ledger: passed.
  • npm run ledger:prs: 6 settlement PRs verified.
  • npm run stats -- --check: passed.
  • npm run scan: 39 files, 0 blocking, 0 warning.
  • Changed workflow and issue-template YAML parsed successfully.
  • git diff --check: passed.

Attestation

  • I reviewed every line of this change myself and I understand it.
  • I used my own subscription account and shared no credentials with anyone.
  • I did not route anyone else's requests through my account.
  • This PR contains no credentials, API keys, tokens, or secrets.

Closes #18

上面这行由维护者追加,正文其余部分未改动。#18 是为这次交付补开的任务——原交付
没有任何托管,而 no-quota 的四条路径都不覆盖一次主动的全仓审计。ledger/pr-evidence.mjs
要求每条 settle 的 PR 正文引用它结算的任务,所以这行是记账的前提。

背景:
- 安全审计确认 P2 隐私边界、退款归属、结算凭据和凭据扫描存在缺口.

主要改动:
- 明确 P2 为可复制源码的临时受信访问,并补充最小授权提示.
- 绑定退款与托管出资人,校验结算 PR 的真实性、任务关联和事件时间.
- 完善特殊文件名、精确白名单、GitHub metadata 和 annotation 安全扫描.

影响范围:
- 隐私说明、账本验证、GitHub Actions 合规流程和相关测试.
- 保持现有 18 条账本记录与余额不变.

验证:
- npm test: 50 项通过.
- npm run ledger: 通过.
- npm run ledger:prs: 6 个历史结算 PR 通过.
- npm run stats -- --check: 通过.
- npm run scan: 39 个文件,0 blocking,0 warning.
- PyYAML: workflow 与 issue template 语法有效.
@mxx1111

mxx1111 commented Aug 25, 2026

Copy link
Copy Markdown
Owner

@AuroraNest 先为六天没有回应道歉。这是一份未被任何任务托管、也没人要求你做的安全审计,而它在队列里躺了六天——这恰恰是这块板子当前最该修的毛病,你的 PR 里有一部分改的就是它。

我把你声称的每一条都在本地复算了一遍,全部成立:

验证项 结果
npm test 50 passed
npm run ledger All invariants hold
npm run ledger:prs Verified 6 settlement pull request(s)
npm run stats -- --check matches computed ledger stats
npm run scan 39 files, 0 blocking, 0 warning
账本历史 18 条、total_issued 100、in_escrow 40,与 main 逐字节一致

最后一条是我最在意的。新增的两条不变量——托管归属、退款必须回到原始出资人——是加在一个已经跑了 18 条记录的账本上的,如果历史里有任何一条违反它们,重放就会失败。没有失败,说明这两条规则不是事后追认现状,而是本来就该在那里。

逐项意见

托管归属与退款绑定(verify.mjs — 直接合。原来的 refund 只检查金额不超过托管额,不检查退给谁,任何人都能把别人托管的 TP 退进自己账户。这是真漏洞,不是理论问题。

结算凭据实证(pr-evidence.mjs — 直接合。之前 settle 条目里的 PR 链接是一段没人验证的字符串,现在要求它是规范的 GitHub PR URL、真实存在、确实关联到那个任务、并且 merged 或被接受后关闭。referencesTask 里对跨仓库引用和纯 #123 的区分处理得比我自己会写的仔细。

NUL framing 与 fail closed(scan-repo.mjs — 直接合,这里有两个改动值得单独说。execSync('git ls-files') 换成 execFileSync-z,处理的是文件名里有换行的情况;而把读文件失败从 continue 改成 throw,修的是一个更难看的问题:原来一个读不出来的被跟踪文件会被静默跳过,凭据扫描器最不该有的行为就是"扫不了就当没事"。

Actions annotation 转义 — 直接合。文件路径里的换行能伪造 ::error 指令,这条在 CI 里是可以被利用的。

allowlist 只允许精确到行 — 直接合。我确认过当前 scan-allow.txt 是空的,所以收紧格式不会让任何现有条目失效。移除 rule-id:* 通配是对的:一个能一键静音整个规则的口子,迟早会被用来让构建变绿。

P2 那一条,我要单独说

这一条超出了修 bug 的范围,它改的是这个项目对外的承诺,所以我不想让它混在"六个安全修复"里一起划过去。

你是对的,原来的写法是过度承诺。 "代码不落接单者磁盘"这句话,在一个接单者自己账号下的 Codespace 里根本不成立——git clone 到别处、scp、甚至复制粘贴,全都能把代码带走。分支保护限制的是写入,从来不限制读取。我把一个只保护了工人凭证的设计,写成了好像也保护了发布者源码的样子。

写这份文档的时候我知道 Codespace 是接单者控制的,但还是写了那句话,因为它读起来更像一个卖点。这是我的问题,不是措辞不严谨的问题。

所以这一条照单全收,包括你加的那三条检查清单——尤其是"授予完整仓库访问前,已经考虑过只放最低必要代码的临时仓库"。这句话把 P2 从一个听着安全的选项,变回了一个需要发布者认真做决定的选项,它本来就该是后者。

同步要改的口径我会跟着这个 PR 一起处理:COMPLIANCE.md 里对 P2 的描述、以及落地页上任何暗示"代码不外流"的说法。

结算

这次交付没有任何任务托管,而 no-quota 的四条路径——reviewredact-auditspecarbitrate——全都要附着在别人已经发布的任务上,没有一条描述一次主动的全仓安全审计。我先想用 no-quota 记账,发现那是把一条不存在的路径硬掰成存在。

所以改成补开一个任务并正常托管:#18,tier L,80 TP,按 GOVERNANCE.md 的价目表。在交付之后才发布任务是不规矩的,我把它写在那个 issue 里而不是藏起来,no-quota 覆盖不到主动审计这个缺口也一并记成了已知问题。

已建 profiles/AuroraNest.md,TP 标为 pending——settle 条目必须指向已合并的 PR 并经 ledger:prs 实证校验,所以记账跟在合并之后,不能提前写。

有一件事需要你确认:这个分支上 no checks reported,CI 从来没在它上面跑过。合并前我会手动触发一次,如果你那边有更方便的做法,说一声。

再说一次谢谢,也再说一次抱歉让你等了六天。

@mxx1111

mxx1111 commented Aug 25, 2026

Copy link
Copy Markdown
Owner

一件卡住的事:这个 PR 是 draft

我准备合并的时候才发现它还挂着 draft,合并被 GitHub 挡下来了。

我不打算替你点 "Ready for review"。 我有那个权限,但 draft 是你的意思表示——
"这还不是一个正式的合并请求"。维护者替你把它转正再合并,等于替你宣告了一句你没说过的
"这个做完了"。这块板子上周刚因为替别人做决定付出过代价,不该在这里再来一次。

所以:如果它已经完成,你点一下 Ready for review,我立刻合并。

进度都已经就位,等的只有你那一下:

如果它还没完成,就别点。 说一句还差什么,我等。八十 TP 的托管躺在那儿不会过期,
比一份被提前定型的工作值钱得多。

顺便说一句和你有关的:你在这个 PR 里改的 verify.mjs,今天已经在挡真金白银了——
新增的托管归属和退款收款人两条不变量,正好用在今天要写的一批条目上。修的不是假想的洞。


追记:合并时 docs/index.html 会有一处冲突,我来解决,不用你动。

等你确认的这段时间里 main 前进了几步——三笔供资、一笔结算、一笔补偿写进了账本,
total_issued 从 100 到 220。落地页上的账本数字是 scripts/render-stats.mjs 生成的,
所以它跟着变了。

而你在这个 PR 里手工把同一行的「9 条不变量」改成了「11 条」——因为你新增了托管归属和
退款收款人两条。两边改的是同一行,合并时 git 会标冲突。

正确的结果是两个改动都要:27 条记录、11 条不变量。我合并时按这个解决,你不需要
rebase,也不需要碰它。

顺带一提,这也说明你那两条不变量已经在干活了:seq 19-27 里有三个 ref 的托管和一笔
退款路径,全部经过了你加的归属检查才落进账本。

背景:
- PR mxx1111#17 需要同步最新 main,新增结算记录发生在交付 PR 合并之后.

主要改动:
- 合入最新 main 并解决账本统计页面冲突.
- 结算证据要求 PR 完成时间不晚于账本结算时间,无效或未来时间继续拒绝.
- 更新回归测试和中英文账本文档.

影响范围:
- 安全加固分支与最新账本记录保持兼容,不修改既有账本历史.

验证:
- npm test: 50 passed.
- npm run ledger: 27 entries, all invariants hold.
- npm run ledger:prs: 7 settlement pull requests verified.
- npm run stats -- --check: passed.
- npm run scan: 45 files, 0 blocking, 0 warning.
- YAML 和 git diff 检查通过.
@AuroraNest
AuroraNest marked this pull request as ready for review August 26, 2026 06:36
@AuroraNest

Copy link
Copy Markdown
Author

已同步最新 main 并解决冲突,当前 head 为 4b5e5eb.

上游新增的 seq 26 在交付 PR 合并 190 秒后才记账,因此将结算证据规则收敛为: PR 的 mergedAt / 已接受的 closedAt 必须有效且不晚于账本结算 ts. 未来时间和无效时间仍然 fail closed,并补了回归测试.

本地验收:

  • npm test: 50 passed
  • npm run ledger: 27 entries, all invariants hold
  • npm run ledger:prs: 7 settlement PRs verified
  • npm run stats -- --check: passed
  • npm run scan: 45 files, 0 blocking, 0 warning
  • YAML, snapshot 和 diff checks: passed

PR 已标记 Ready for review. 新 CI 因 fork workflow 显示 action_required,需要 maintainer 再批准一次: https://github.com/mxx1111/spare-cycles/actions/runs/32938902517

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
这个 PR 已经 7 天没有新提交、作者也没有回复,它关联任务上的托管因此一直被占着,既不结算也不释放。

PR 不会被关闭——这是你的工作,随时可以接着做。被释放的只是任务上的认领,任务重新开放给其他人。

如果你还在做,回一句就行。

No commits or author replies for 7 days. The claim is released; this PR stays open.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Task] Security audit of the board itself — retroactive for #17

2 participants