Code Review Bench PR #25434 - fix: get bookings handler for pbac and fallback roles#1
Conversation
| fallbackRoles: MembershipRole[]; | ||
| orgId?: number; | ||
| }): Promise<number[]> { | ||
| return this.getTeamIdsWithPermissions({ userId, permissions: [permission], fallbackRoles }); |
There was a problem hiding this comment.
🚨 Bug: orgId silently dropped in getTeamIdsWithPermission
In PermissionRepository.getTeamIdsWithPermission(), the orgId parameter is destructured from the input but is not forwarded to the delegated call to this.getTeamIdsWithPermissions(). This means organization-scoped filtering never takes effect when calling the singular getTeamIdsWithPermission method — which is exactly the entry point used by the getBookings handler (via permissionCheckService.getTeamIdsWithPermission).
Impact: When a user belongs to multiple organizations, the query will return team IDs from all organizations instead of only the user's current organization. This is a privilege escalation / data leakage issue — an org admin of Org A could see bookings from Org B's teams if they also have a membership in Org B.
The fix is to include orgId in the forwarded call.
Was this helpful? React with 👍 / 👎
| return this.getTeamIdsWithPermissions({ userId, permissions: [permission], fallbackRoles }); | |
| return this.getTeamIdsWithPermissions({ userId, permissions: [permission], fallbackRoles, orgId }); |
- Apply suggested fix
| ); | ||
|
|
||
| const isCurrentUser = filters.userIds.length === 1 && user.id === filters.userIds[0]; | ||
| const isCurrentUser = filters.userIds.includes(user.id); |
There was a problem hiding this comment.
⚠️ Security: Relaxed isCurrentUser check enables permission bypass
The isCurrentUser check was changed from:
const isCurrentUser = filters.userIds.length === 1 && user.id === filters.userIds[0];to:
const isCurrentUser = filters.userIds.includes(user.id);The old logic required that the only requested user was the current user. The new logic only checks that the current user is among the requested users. This changes the security semantics: if a user requests userIds: [self, otherUser] where otherUser is outside their org/team, the old code would correctly reject the request (length > 1, so isCurrentUser = false, and areUserIdsWithinUserOrgOrTeam = false → FORBIDDEN). The new code would set isCurrentUser = true, bypassing the permission check entirely and allowing the user to see bookings for otherUser.
Impact: A user can include their own ID alongside any other user ID(s) to bypass the permission check and access bookings they shouldn't be able to see.
The fix should restore the original stricter semantics, or ensure the condition properly validates all requested userIds (not just that the current user is among them).
Was this helpful? React with 👍 / 👎
| const isCurrentUser = filters.userIds.includes(user.id); | |
| const isCurrentUser = filters.userIds.length === 1 && filters.userIds[0] === user.id; |
- Apply suggested fix
There was a problem hiding this comment.
Configure merge blocking · Maintainers can dismiss this review. Gitar never approves changes.
Code Review 🚫 Blocked 0 resolved / 2 findingsPBAC refactoring has a critical bug where 🚨 Bug:
|
| Auto-apply | Compact |
|
|
Was this helpful? React with 👍 / 👎 | Gitar
Benchmark PR for Gitar evaluation
Original PR: agentic-review-benchmarks#1
fix: get bookings handler for pbac and fallback roles
Summary by Gitar
PermissionCheckServiceusingbooking.readpermission and[ADMIN, OWNER]fallback rolesorgIdparameter toIPermissionRepositoryfor multi-org filteringgetTeamsWithPBACPermissionsandgetTeamsWithFallbackRolesprivate methodsget.handler.test.tsThis will update automatically on new commits.