fix(security): enforce current organization skill ownership - #3680
Conversation
|
🦞👀 Pull request received. I will update this pull request when review starts. ClawSweeper review completeClawSweeper finished reviewing this revision. The review result is being finalized. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Codex review: needs maintainer review before merge. Reviewed September 11, 2026, 11:47 AM ET / 15:47 UTC. ClawSweeper reviewWhat this changesRequire current organization ownership permissions for skill transfers, deletion, and restoration, including rechecking pending transfers after membership changes. Merge readiness✅ Ready for maintainer review Keep open: current main still contains the authorization bypass, and this collaborator-authored PR provides a focused repair. No blocking patch findings were identified. Priority: P0 Review scores
Verification
How this fits togetherClawHub’s backend receives authenticated skill-management requests from its website and CLI. Publisher authorization determines whether those requests may change skill ownership or marketplace visibility. flowchart TD
A[Authenticated management request] --> B[Resolve skill and actor]
B --> C[Check current publisher permissions]
C --> D[Reject unauthorized request]
C --> E[Create pending transfer]
E --> F[Recheck requester on acceptance]
F --> G[Update ownership or cancel transfer]
C --> H[Apply guarded delete or restore]
Before mergeNone. Agent review detailsSecurityNone. Review metrics
Technical reviewBest possible solution: Keep current publisher membership authoritative at each mutation boundary while preserving personal-owner compatibility and existing moderation safeguards. Do we have a high-confidence way to reproduce the issue? Yes, from source: retain an organization skill’s historical ownerUserId, revoke that user’s membership, then request a transfer or delete/restore the skill; main bypasses the membership check. This review did not execute the reproduction. Is this the best way to solve the issue? Yes—best fix: reuse the existing ownership helper at the final mutation boundaries. Rewriting historical owner IDs would require migration and would not itself revalidate pending transfers. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning medium; reviewed against cbfee7343ddc. LabelsLabel changes:
Label justifications:
EvidenceWhat I checked:
Likely related people:
Rating scale
Overall follows the weaker of proof and patch quality. Workflow
|
Former publishers retained authority over organization skills through the historical
ownerUserId. Transfer requests and delete/restore now use current publisher authorization, and transfer acceptance rechecks the requester's authority after membership removal or downgrade.Addresses GHSA-9558-q4f9-324f. The advisory is published with the deployed revision and regression evidence.
Verification
cbfee7343ddc867316dd9b3de6fa8856730f9f41reproduced successful former-publisher transfer requests, acceptance after revocation/downgrade, and delete/restore.http://127.0.0.1:3320, using synthetic organization/member/recipient fixtures: transfer request denied; pending acceptance cancelled; delete denied; restore denied; organization ownership preserved. No production data or accounts were exercised.bun run ci:staticpassed.bun run ci:unitpassed: 6,627 tests; 497 passing files, 1 skipped.bun run ci:types-buildpassed, including root, schema, CLI, admin TypeScript and production build.bunx convex dev --once --codegen disablepushed and typechecked the candidate successfully on the disposable local backend..agents/skills/autoreview/scripts/autoreview --mode local --no-web-search: clean, no actionable findings.Best-fix verdict: best. Reusing the shared publisher authorization keeps organization membership authoritative without changing personal-owner or staff permissions. Changing stored historical user IDs would not revalidate pending requests and would require a data migration.
Combined release validation:
ci:static,ci:unit(6,656 passing tests), andci:types-buildpassed onf3cd9104981d1875cc2945418172837297afcb5d. The protected Test frontend passed four HTTP checks, two browser checks, and an archive download check.Deployment verified
Merged and deployed in
8c2de6c506bb4efabe3f0c2ffb8370b9e23d4650. Test deployment and Production deployment succeeded for that exact SHA. Live reads/downloads/image rendering and browser smoke tests pass; forged ingress is rejected. The active Production catalog rollout was restored after backend deployment. The superseded private security-fork PR is closed.