Skip to content
IBMGHSA-rj22-3ww8-gmv4

Broken Acess Control in Team Join Approval Flow

MediumPublished Aug 25, 2026

### Summary The team’s approval to join flow fails to properly validate the user’s privileges over the target team. ### Details The approval flow requires the caller to be the owner of the `team_id` path parameter, but the approval code ignores that parameter when loading the join request. `TeamManagementService.approve_join_request` looks up the request only by `request_id`, then adds the member to `join_request.team_id` and commits. If a team owner calls the endpoint with their own `team_id` but with a `request_id` belonging to some other team, the service approves the other team’s request and adds the user to that team, despite the caller not having any privileges there. ### PoC 1. Attacker obtains an authenticated account with `teams.manage_members` capability and owner role on at least one team they control (Team A). 2. Attacker learns or guesses a valid pending `request_id` belonging to another team (Team B), e.g., "ask to" join response. <img width="1221" height="423" alt="image" src="https://github.com/user-attachments/assets/4ee9cc0f-6848-417f-a642-acf2561f2272" /> 3. Attacker sends `POST /admin/teams/{teamA_id}/join-requests/{requestB_id}/approve` with their valid auth...

GitHub advisory

Affected versions

PackageAffectedFixed in
mcp-contextforge-gateway
PyPI
< v1.0.6v1.0.6
Details and references

### Summary The team’s approval to join flow fails to properly validate the user’s privileges over the target team. ### Details The approval flow requires the caller to be the owner of the `team_id` path parameter, but the approval code ignores that parameter when loading the join request. `TeamManagementService.approve_join_request` looks up the request only by `request_id`, then adds the member to `join_request.team_id` and commits. If a team owner calls the endpoint with their own `team_id` but with a `request_id` belonging to some other team, the service approves the other team’s request and adds the user to that team, despite the caller not having any privileges there. ### PoC 1. Attacker obtains an authenticated account with `teams.manage_members` capability and owner role on at least one team they control (Team A). 2. Attacker learns or guesses a valid pending `request_id` belonging to another team (Team B), e.g., "ask to" join response. <img width="1221" height="423" alt="image" src="https://github.com/user-attachments/assets/4ee9cc0f-6848-417f-a642-acf2561f2272" /> 3. Attacker sends `POST /admin/teams/{teamA_id}/join-requests/{requestB_id}/approve` with their valid auth token. 4. The router validates ownership only for `teamA_id` and calls `approve_join_request(request_id, approved_by=attacker_email)` without binding `request_id` to `teamA_id`. 5. Service loads join request by `request_id` only, then creates membership and RBAC assignment for `join_request.team_id` (Team B), marking request approved. 6. Result: unauthorized cross-team membership approval occurs; attacker has modified Team B’s access-control state despite lacking ownership/privileges in Team B. ``` POST /admin/teams/{teamA_id}/join-requests/{requestB_id}/approve HTTP/1.1 Host: 127.0.0.1:8000 Content-Length: 0 X-CSRF-Token: <replace_with_token> HX-Current-URL: http://127.0.0.1:8000/admin/#teams HX-Request: true User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36 Content-Type: application/x-www-form-urlencoded Origin: http://127.0.0.1:8000 Referer: http://127.0.0.1:8000/admin/ Accept-Encoding: gzip, deflate, br Cookie: mcpgateway_csrf_token=<replace_with_token>; jwt_token=<replace_with_jwt> ``` ### Impact This is an authorization logic flaw enabling any team owner to approve memberships for teams they do not control. Andrea `zi0Black` Cappa @ Aptos Labs

Severity from
GitHub (reviewed advisory)
Weakness
CWE-284

More IBM advisories

All IBM

Critical advisories by email

Wednesdays: the week’s critical and high advisories in the AI and data stack, with the fixed versions. Only in weeks that have some.

Double opt-in. Unsubscribe any time.