fix(plugin-security): 约束 self-delegation position anchor 防横向可见性越权(#830 follow-up) - #2945
Merged
Merged
Conversation
…follow-up) cloud#830 (C1 position-anchor) 把 sys_user_position.business_unit_id 变成可见性 load-bearing(readScope 的深度锚定)。自助代理(D3)路径 assertSelfDelegation 对该 anchor 无任何 subtree/来源约束:持有一个 delegatable、非 admin-scope、锚定在低层 BU 的 position 的用户,可把它代理给同谋并把 business_unit_id 设成任意高层/祖先 BU,从而 泄露该 BU 整棵子树的成员记录可见性——超出委派人自身范围;互相代理可双向获得。 修复:self-delegation 的 business_unit_id 必须落在委派人自己对该 position 的有效 anchor 之内(自己直接持有行 anchor 的子树,或持有行无 anchor 时其成员 BU 的子树)—— 与 D12 委派管理员「assignments 必须落自己 subtree」同精神。fail-closed:无法证明落在 委派人范围内的 anchor 一律拒。无 anchor 的代理行保持原行为(代理人解析到自己的成员 BU,非放宽)。「锚定只收窄不放宽」不变量在 D3 路径重新成立。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019QRUvVfpvSycAHMMF2xTxs
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 11 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
os-zhuang
marked this pull request as ready for review
July 15, 2026 03:45
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
漏洞(MEDIUM,横向可见性越权 / lateral escalation)
cloud#830(C1 position-anchor,已合并)把
sys_user_position.business_unit_id从「reserved」变成可见性 load-bearing:它是readScope的深度锚定,unit/unit_and_below的持有者可见的 owner 集合以该 BU 为根(unit_and_below覆盖整棵子树)。委派管理员的自助代理(D3 self-delegation)路径
assertSelfDelegation(packages/plugins/plugin-security/src/delegated-admin-gate.ts)此前对business_unit_id没有任何 subtree/来源约束。后果:delegatable: true、带unit/unit_and_belowreadScope 的非 admin-scope position P(锚定在低层 BU)。business_unit_id设成任意高层 / 祖先 BU。unit_and_below整棵子树)成员记录的可见性——超出 Alice 自己的范围。resolver 的「锚定只收窄不放宽」断言在 anchor 是成员 BU 祖先时不成立——而 D3 路径正是唯一没堵住这条的地方。主攻击面(直接自写
sys_user_position、自我代理、委派管理员路径的 anchor 落自己 subtree)此前均已封死。修法选择与理由
采用任务的首选方案(约束而非禁止),理由:产品语义上 D3 代理本就允许携带 anchor(例如把「华东销售经理」职务代理给某人、锚定在华东某子单元)——一刀切禁止 anchor 会砍掉合法用法。改为强制收窄不放宽:
「有效 anchor」= 委派人自己直接持有该 position 的行的 anchor 子树;若该直接持有行本身无 anchor,则回退到委派人成员 BU 的子树(无锚持有解析到本人成员 BU)。这与 D12 委派管理员路径「assignments 必须落自己 subtree」(
assertAssignmentWrite,L392-402)同精神、复用同款 subtree 逻辑。实现:
activeHoldings现返回每个持有行的businessUnitId;新增resolveSubtreeById/delegatorAnchorSubtree(resolveSubtree重构复用之,行为不变);assertSelfDelegation新增步骤 4b anchor 收窄校验。测试矩阵(实测全绿,401 passed)
sys_user_position仍封禁pnpm --filter @objectstack/plugin-security test→ 18 files / 401 tests passed;tsc --noEmit0 error;build通过。是否彻底堵住
对 load-bearing 的
unit_and_below情形:Bob 的 owner 集合 ⊆ Alice 的 owner 集合,「锚定只收窄不放宽」不变量在 D3 路径重建。祖先 / 任意高层 / 无关 BU 的锚定被 fail-closed 拒绝,主向量关闭。存疑点 / reviewer 注意
unit(单层,非_and_below)readScope 下的子孙 anchor:本修复用 subtree 包含作边界(与 D12 admin 路径一致)。若 P 的 readScope 是纯unit,Alice 锚定 east 只看 east 一层,而允许 Bob 锚定 east 的子孙east_sales在严格意义上让 Bob 看到 Alice 看不到的一层(横向而非放宽)。这与 D12 委派管理员路径既有的同一边界取舍一致(该路径也用 subtree),且主向量(祖先/高层放宽)已完全关闭。若要对纯unit也精确收敛,需在 gate 里解析 position 所分发各 set 的 per-object readScope——依赖 cloud enterprise resolver 语义,超出本 follow-up 范围,建议单独 issue 跟踪。resolveSubtreeById(既有resolveSubtree按 name 解析根后同样走子树遍历,已重构复用)。security-enterprise/hierarchy/resolver.ts的anchoredBusinessUnits)不在本仓库 checkout 内,anchor→owner 语义依 ADR-0090 Addendum 与任务描述推断;建议 reviewer 对照 cloud#830 确认「无 anchor = 解析到持有者成员 BU」这一回退语义无误(本修复的成员 BU 兜底依赖它)。Reviewer checklist
unit子孙 anchor)取舍可接受,或决定单开 issue关联
🤖 Generated with Claude Code
https://claude.ai/code/session_019QRUvVfpvSycAHMMF2xTxs