Scoped admin OAuth DCR endpoints ignore token_teams restrictions and expose global registered clients
Medium6.4Published Sep 2, 2026
### Confidence Note This report is based on source analysis of version `1.0.4` and I have not yet dynamically validated it against a live instance. ### Summary `get_current_user_with_permissions()` propagates `token_teams` into the authenticated user context, and other sensitive admin endpoints explicitly reject narrowed admin sessions when `token_teams is not None`. However, the OAuth DCR management endpoints only call `_require_admin_user()`, which checks `is_admin` but ignores `token_teams`. As a result, a scoped admin token appears able to list, retrieve, and delete global `RegisteredOAuthClient` records outside its allowed team scope. ### Impact If this behavior is reachable in deployment, an administrative token that is intentionally narrowed to specific teams may still access the global OAuth dynamic client registration management surface. That would allow cross-scope visibility into registered clients and may also allow deletion of client registrations outside the token's intended authorization boundary. ### Affected Endpoints - `GET /registered-clients` - `GET /registered-clients/{gateway_id}` - `DELETE /registered-clients/{client_id}` ### Technical Details The R...
Affected versions
| Package | Affected | Fixed in |
|---|---|---|
| mcp-contextforge-gateway PyPI | < v1.0.8 | v1.0.8 |
Details and references
### Confidence Note This report is based on source analysis of version `1.0.4` and I have not yet dynamically validated it against a live instance. ### Summary `get_current_user_with_permissions()` propagates `token_teams` into the authenticated user context, and other sensitive admin endpoints explicitly reject narrowed admin sessions when `token_teams is not None`. However, the OAuth DCR management endpoints only call `_require_admin_user()`, which checks `is_admin` but ignores `token_teams`. As a result, a scoped admin token appears able to list, retrieve, and delete global `RegisteredOAuthClient` records outside its allowed team scope. ### Impact If this behavior is reachable in deployment, an administrative token that is intentionally narrowed to specific teams may still access the global OAuth dynamic client registration management surface. That would allow cross-scope visibility into registered clients and may also allow deletion of client registrations outside the token's intended authorization boundary. ### Affected Endpoints - `GET /registered-clients` - `GET /registered-clients/{gateway_id}` - `DELETE /registered-clients/{client_id}` ### Technical Details The RBAC layer includes `token_teams` in the authenticated user context: - `mcpgateway/middleware/rbac.py:443-455` The helper used by the OAuth DCR management endpoints only verifies `is_admin`: - `mcpgateway/routers/oauth_router.py:192-203` The affected endpoints rely on that helper and do not reject narrowed admin sessions: - `mcpgateway/routers/oauth_router.py:988-1033` - `mcpgateway/routers/oauth_router.py:1040-1084` - `mcpgateway/routers/oauth_router.py:1093-1136` By contrast, another sensitive admin surface explicitly blocks narrowed tokens by checking whether `token_teams` is not `None`: - `mcpgateway/routers/tokens.py:624-633` The registered OAuth client objects appear to be stored globally and are queried directly without team scoping in these endpoints: - `mcpgateway/db.py:5317-5335` This combination suggests that a scoped admin session may enumerate or delete registered OAuth clients beyond its intended scope. ### Reproduction Idea Based on source analysis, the likely reproduction path is: 1. Obtain an authenticated admin token or session that is intentionally narrowed through `token_teams`. 2. Call `GET /registered-clients`. 3. Observe whether the response includes globally registered OAuth clients outside the teams allowed by the token. 4. Call `GET /registered-clients/{gateway_id}` for a gateway outside the narrowed scope. 5. Attempt `DELETE /registered-clients/{client_id}` against a registration outside the token's allowed team scope. 6. If successful, this confirms cross-scope authorization bypass. ### Root Cause The authorization model distinguishes between full admin access and narrowed admin access, but the OAuth DCR management endpoints enforce only the admin bit and ignore the narrowing metadata carried in `token_teams`. ### Suggested Remediation - Apply the same un-narrowed admin check used in other sensitive endpoints to the OAuth DCR management endpoints. - Enforce explicit scope validation before listing, retrieving, or deleting registered OAuth clients. - Add tests covering narrowed admin tokens against all DCR management routes. - Review other admin-only endpoints for similar `is_admin`-only checks that ignore `token_teams`. ### Code References - `mcpgateway/middleware/rbac.py:443-455` - `mcpgateway/routers/oauth_router.py:192-203` - `mcpgateway/routers/oauth_router.py:988-1033` - `mcpgateway/routers/oauth_router.py:1040-1084` - `mcpgateway/routers/oauth_router.py:1093-1136` - `mcpgateway/routers/tokens.py:624-633` - `mcpgateway/db.py:5317-5335`
- CVSS 3.1
- CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N
- Severity from
- GitHub (reviewed advisory)
More IBM advisories
All IBM| Date | Advisory | Severity | Fixed in |
|---|---|---|---|
| Sep 3 | IBM Netezza Software: remote attacker could exploit misconfigurations or naming | Medium6.5 | No fix yet |
| Sep 3 | IBM Netezza Software: information disclosure | Medium5.3 | No fix yet |
| Sep 3 | IBM Netezza Software: unauthorized user could inject data into log messages | Medium5.3 | No fix yet |
| Sep 3 | IBM Netezza Software: information disclosure | Medium5.9 | No fix yet |
| Sep 3 | IBM Netezza Software: information disclosure | High7.5 | No fix yet |
| Sep 3 | IBM Qiskit SDK: denial of service | Medium6.2 | No fix yet |