security: close 6 more write-authorization gaps (#131 Phase 3 sweep)
A full sweep of every write route in musehub/api/routes/ (per #131's Phase 3) found six more gaps beyond the original wire-protocol bug, all of the same class: relying only on require_scope(...) (an agent-capability gate that passes human identities through unconditionally) or on nothing at all, with zero check that the caller has any real relationship to the resource being written.
Fixed: - POST /repos/{repo_id}/branches/{name}/reset -- force-moves any branch to any commit with no check at all. Now requires owner-or-admin (matches the trust level of other settings-changing operations). - POST/POST /repos/{repo_id}/proposals/{id}/close|reopen -- no repo fetch, no auth check whatsoever; any authenticated identity could close or reopen any proposal in any repo, including resurrecting merged ones. Now requires owner-or-write/admin-collaborator, matching merge_proposal. - POST /repos/{repo_id}/sessions (+ /{id}/stop) -- no write-access check. Now requires owner-or-write/admin-collaborator. - POST /repos/{repo_id}/symbol-index/rebuild -- no write-access check (lower severity: derived data, but still an uncontrolled cross-repo write + compute-cost trigger against private repos). Now requires owner-or-write/admin-collaborator. - POST/DELETE /api/orgs/{org}/members/{handle} -- add_org_member and remove_org_member never checked the actor at all, only stamped them as commit author. Any authenticated identity could add itself as an admin member of any org, or remove any member from any org. Added _assert_org_write_access: owner-or-admin-member, with a bootstrap exception for a brand-new org's first member (otherwise nobody could ever become the first admin). - Collaborator-management actor-permission checks (REST collaborators.py, MCP write_tools/repos.py and write_tools/collaborators.py) didn't filter accepted_at IS NOT NULL, so a pending (not yet accepted) admin invite could exercise admin rights before accepting. Added the filter, matching the pattern already correct in musehub_repository.check_write_access.
16 new regression tests (tests/test_authz_phase3_sweep.py) prove each gap closed while confirming legitimate access still works. Full existing suite for every touched area (branch reset, proposals, sessions, collaborators, MCP write-tools, symbol intelligence -- 379 tests total) passes with zero regressions.
Semantic Changes
79 symbols
Files Changed
+1
~7
1063 in snapshot
0 comments
muse hub commit comment sha256:972eba74056d449071cb89543bfc58de94138f3826d2fd1e31491583cd8298a7 --body "your comment"
No comments yet. Be the first to start the discussion.