Skip to content

Scoped admin OAuth DCR endpoints ignore token_teams restrictions and expose global registered clients

Moderate
brian-hussey published GHSA-gj7g-7r6g-jc8v Aug 25, 2026

Package

pip mcp-contextforge-gateway (pip)

Affected versions

< v1.0.7

Patched versions

v1.0.7

Description

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

Severity

Moderate

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
Low
User interaction
None
Scope
Changed
Confidentiality
Low
Integrity
Low
Availability
None

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N

CVE ID

No known CVE

Weaknesses

No CWEs