Summary
listPlans (internal/api/handler_plans.go) gates only on view:plans and passes the client-supplied account_ids straight to the store query without intersecting them with the caller's getAllowedAccounts. The no-filter path returns every plan across all accounts. This is pre-existing (not introduced by PR LeanerCloud/cloud-commitments-cli#994), but PR LeanerCloud/cloud-commitments-cli#994's OR NOT EXISTS arm broadens the surface of an already-unscoped endpoint by also returning all zero-account ("Unassigned") plans regardless of caller scope.
Concern
A non-admin user scoped to a subset of accounts may be able to enumerate plans (including Unassigned legacy plans) belonging to accounts outside their allowed_accounts, depending on how view:plans is granted.
Acceptance criteria
- Decide whether
listPlans should intersect the requested account_ids with getAllowedAccounts for non-admin callers (and how Unassigned plans should be scoped: visible to all view:plans holders, or only to admins?).
- If yes, add the intersection + a cross-tenant regression test (a scoped user does not see another account's plans).
- Confirm against the group-only authz model (Administrators vs Standard vs Read-Only).
Summary
listPlans(internal/api/handler_plans.go) gates only onview:plansand passes the client-suppliedaccount_idsstraight to the store query without intersecting them with the caller'sgetAllowedAccounts. The no-filter path returns every plan across all accounts. This is pre-existing (not introduced by PR LeanerCloud/cloud-commitments-cli#994), but PR LeanerCloud/cloud-commitments-cli#994'sOR NOT EXISTSarm broadens the surface of an already-unscoped endpoint by also returning all zero-account ("Unassigned") plans regardless of caller scope.Concern
A non-admin user scoped to a subset of accounts may be able to enumerate plans (including Unassigned legacy plans) belonging to accounts outside their
allowed_accounts, depending on howview:plansis granted.Acceptance criteria
listPlansshould intersect the requestedaccount_idswithgetAllowedAccountsfor non-admin callers (and how Unassigned plans should be scoped: visible to allview:plansholders, or only to admins?).