第三阶段安全审查意见(Claude 2026-11-02,独立复核 301337ea)
这是 kw-share.md 的附页。审查对象是 git diff 8e513d2e..301337ea。审查只读,用合成数据,在 301337ea 的干净快照上复现。下列各项都已用探针复现。探针在 Claude 的草稿区(probes-p3/:a-raw-submission、b-personal-parser-share、c-named-doc、d-connector、e-leases、f-lows),可以照着写回归测试;需要具体步骤时向 Claude 要。
先完成 kw-share.md 中“全量 CI 回归与修正方向”一节,再修本页各项。每项附回归测试;修完在 kw-share.md 的“做了的”“验证”补写,并列出本页各项的处理结果。
高
- 个人工作流可读管理员的命名文档
- 位置:
hub/server/docs.ts:182-194。 - 原因:成员读取命名文档的检查只有两条:运行属于本人,且运行的包声明了
doc:doc输入。现在成员发布的个人工作流就能同时满足这两条:forUser接受个人空间,本人总能使用自己的个人包,而validatePack对输入的accepts没有限制。 - 后果:成员发布一个输入声明为
accepts:["doc:doc"]的个人工作流,启动运行并绑定doc:doc:<名称>,就能读到完整的命名文档(拓扑、地址规划、策略表等只给管理员的内容)。
- 位置:
- 个人工作流可借团队凭据读业务系统
- 位置:
hub/connectors/connectors.ts:331, 350-382。 - 原因:外部读取只检查两件事:某个启用的资源声明了该类型,且调用者是启用的账户。原先的把关是只有管理员分配的团队工作流才会触发
external.accepts/read(hub/runs/engine/inputs.ts:194)。个人工作流绕开了这道把关,违反决定 131“业务系统接入只在团队空间”。 - 后果:未获分配的成员读到业务数据。读回的原始响应能通过
#shareSource的资格检查(spaces.ts:446-461),可以经提交共享进入团队,被没有任何包权限的成员读到。
- 位置:
- 已受理的原始提交在读者变化后泄露私有依据
- 位置:
hub/runs/engine/readers.ts:79,以及按记录绑定输入的guardedRecords(inputs.ts:141)。 - 原因:提交记录只按当前的运行可见性和不可变的受理结果放行,不按当前的依据可读性。
resultReadableBy只对未受理的结果重查依据(grounds.ts:127-133)。 - 后果:结果受理后,若授权被收回,或运行分享给了从未获授权的成员,结果本身会正确隐藏;但原始提交仍能作为
rec:输入绑定到新运行,其中复制的私有引文经新运行的src:可读。这是第二阶段第二轮第 4 项的残留:被拒的提交已经堵住,已受理的还没有。
- 位置:
修正方向(对应第 1、2 项,并兼顾中危第 2 项):
- 个人工作流和个人通用技能只允许以下输入:上传、个人知识和团队知识、Hub 生成的文件。
- 不得声明以下内容:命名文档(
doc:doc等)、业务系统接入的类型、租约、设备派发或其他外部效果。 - 在个人发布时校验并拒收,拒收码先登记;启动运行时再检查一次,作纵深防护。
- 移交到团队时沿用团队的发布检查,管理员分配之后才可使用这些能力。
第 3 项:已受理的原始提交在每个读者读取或绑定时,按当前依据可读性重新判断,与 resultReadableBy 一致。缺失与无权限的回应保持相同。
中
- 个人解析器能通过提交共享的逐字核对
- 位置:
hub/refs/skills.ts:290-307、hub/refs/resolve.ts:360、spaces.ts:485-488。 - 原因:
forReference会返回读者当前获授权的个人解析器,而提交共享的“引文逐字一致”检查以提交人为读者。成员可以发布一个返回任意文字的个人解析器,用它引用团队可共享的来源来写个人条目,再提交共享。 - 后果:伪造的引文通过核对,团队条目显示“已核验”。其他成员读不到这个解析器,无法复核。
- 修正:提交共享(以及团队侧的任何核验)只认团队可用的解析器;依据经个人解析器取得时拒收,拒收码先登记。
- 位置:
- 个人工作流可占用共享的租约命名空间
- 位置:
hub/runs/engine/start.ts:164-260。 - 原因:租约前缀是包内的自由文本,个人工作流没有审查。
- 后果:成员可以声明
bed/之类的前缀,拿到不过期的租约并登记子前缀,干扰团队的测试台预约。 - 修正:同高危的修正方向,个人工作流不得使用租约。
- 位置:
低
grounds_withdrawn暴露读者无权读取的上级条目引用:spaces.ts:426-439。只返回读者有权读取的引用,其余只给数量,不给路径。- 提交共享的
team_path没有做凭据扫描:spaces.ts:464只做路径检查,而directory()还会扫描凭据(:374)。补上相同的扫描。
审查确认无误的部分
- 结果依据规则在受理路径上覆盖了全部现有读者:新提交、缓存回执重放和重新核验都经过检查。授权收回后,结果与回执都会正确隐藏。
- 提交共享的检查顺序与来源资格判断正确;它不读取其他成员的个人空间,产品目录不能作为写入目标。
- 取代只作用于本人由同一个人条目提交的团队条目。撤回:提交人只能撤回自己的,管理员可以撤回任何人的。
- “记录”页对管理员的过滤:成员之间的授权不显示;管理员只看到授权给全体管理员的记录和全部共享回执;伪造索引也被排除。
- 个人包的授权:管理员没有绕过途径;技能命名空间已冻结,并在运行时按读者和发起人重查;移交到团队需要发布权并重新核验,不扩大旧运行的读者。
rec:拒绝读取空间、共享和个人包类的记录;被拒的原始提交保持隐藏。
复核时运行的检查
- 在
301337ea的快照上:类型检查、合约检查通过;定向单元组 664 项通过,0 失败;受影响的验收组(06、11、12、13、14、15、16、17、19、21、30、33、39、46、47)55 项通过,0 跳过。 - 没有运行全量回归、Linux 隔离、备份/恢复/部署或来源归档检查。