CVE-2026-71424 Overview
CVE-2026-71424 is an information disclosure vulnerability in Onyx, an open-source AI platform. The flaw affects the Model Context Protocol (MCP) API endpoints GET /api/mcp/servers and GET /api/mcp/servers/persona/{persona_id}. Per-user OAuth tokens are copied into a shared administrative MCPConnectionConfig row, then returned in auth_template.headers to any authenticated BASIC_ACCESS user. Any low-privileged authenticated user can retrieve another user's OAuth Authorization header. The issue is fixed in Onyx versions 3.1.10, 3.2.14, and 4.0.0.
Critical Impact
A low-privileged authenticated user can retrieve another user's OAuth bearer token and impersonate them against upstream MCP-connected services, leading to cross-tenant data exposure and account takeover on downstream integrations.
Affected Products
- Onyx versions prior to 3.1.10 (3.1.x branch)
- Onyx versions prior to 3.2.14 (3.2.x branch)
- Onyx versions prior to 4.0.0 (4.x branch)
Discovery Timeline
- 2026-08-17 - CVE-2026-71424 published to NVD
- 2026-08-18 - Last updated in NVD database
Technical Details for CVE-2026-71424
Vulnerability Analysis
Onyx exposes MCP server configurations through two REST endpoints intended to return per-user connection metadata. In vulnerable releases, the token-persistence logic in OnyxTokenStorage.set_tokens and OnyxTokenStorage.set_client_info (in backend/onyx/server/features/mcp/api.py) writes per-user OAuth material into two locations: the user-scoped row and a shared administrative row identified by self.alt_config_id.
The helper _db_mcp_server_to_api_mcp_server then serializes the shared admin row's auth_template.headers field back to callers. Because the shared row now contains the last writer's bearer token, any authenticated BASIC_ACCESS user calling either endpoint receives that other user's Authorization: <token_type> <access_token> header. This is a classic information exposure defect [CWE-200].
Root Cause
The shared admin MCPConnectionConfig row is intended to act only as an OAuth client_info registry shared across all users of a given MCP server. The vulnerable code incorrectly promoted per-user state, specifically resolved Authorization headers and access tokens, onto that shared row. The API serializer had no filter to strip user-scoped fields before returning the shared row.
Attack Vector
An attacker requires only a valid BASIC_ACCESS account on the Onyx instance. After any other user completes an OAuth flow against an MCP server, the attacker issues an authenticated GET request to /api/mcp/servers or /api/mcp/servers/persona/{persona_id}. The response includes the victim's live Authorization header, which the attacker replays directly against the upstream MCP-connected service.
"Authorization": f"{tokens.token_type} {tokens.access_token}"
}
update_connection_config(config.id, db_session, config_data)
- if self.alt_config_id:
- update_connection_config(self.alt_config_id, db_session, config_data)
- # signal the oauth callback that token exchange is complete
- r = get_redis_client()
- r.rpush(key_tokens(str(self.alt_config_id)), tokens.model_dump_json())
- r.expire(key_tokens(str(self.alt_config_id)), OAUTH_WAIT_SECONDS)
+ # The shared admin row is intentionally NOT written here: it
+ # serves as the OAuth `client_info` registry shared across all
+ # users of this MCP server (see `get_client_info`). Per-user
+ # state (access tokens and resolved `Authorization` headers)
+ # belongs only on the per-user row. The Redis push below is
+ # what `process_oauth_callback` blocks on to know token exchange
+ # has completed; the admin config id is the only stable
+ # identifier shared between the two contexts.
+ if self.alt_config_id:
+ r = get_redis_client()
+ r.rpush(key_tokens(str(self.alt_config_id)), tokens.model_dump_json())
+ r.expire(key_tokens(str(self.alt_config_id)), OAUTH_WAIT_SECONDS)
async def get_client_info(self) -> OAuthClientInformationFull | None:
with get_session_with_current_tenant() as db_session:
Source: GitHub Commit b1039378. The patch removes the update_connection_config(self.alt_config_id, ...) call that promoted per-user tokens into the shared admin row, while retaining the Redis signaling used by process_oauth_callback.
Detection Methods for CVE-2026-71424
Indicators of Compromise
- Application logs showing GET /api/mcp/servers or GET /api/mcp/servers/persona/{persona_id} requests from BASIC_ACCESS accounts that never completed an OAuth flow for that MCP server.
- Upstream MCP service audit logs showing API calls whose source IP or user-agent does not match the OAuth token owner's normal client fingerprint.
- Repeated enumeration of /api/mcp/servers/persona/{persona_id} across many persona_id values from a single low-privileged session.
Detection Strategies
- Correlate Onyx access logs against user-to-MCP-server ownership records; flag any user retrieving MCP server metadata for a server they did not configure.
- Alert on responses from /api/mcp/servers endpoints that include populated auth_template.headers.Authorization fields when returned to non-admin roles.
- Baseline OAuth token usage on upstream services and alert on new client IPs presenting an existing bearer token.
Monitoring Recommendations
- Enable verbose audit logging on the backend/onyx/server/features/mcp/api.py routes and forward to a centralized log store.
- Monitor for privilege-tier mismatches: any BASIC_ACCESS principal touching MCP configuration endpoints warrants review.
- Review historical logs going back to the deployment date of any pre-3.1.10, pre-3.2.14, or pre-4.0.0 release to identify prior exposure.
How to Mitigate CVE-2026-71424
Immediate Actions Required
- Upgrade Onyx to 3.1.10, 3.2.14, or 4.0.0 immediately, matching your current release branch.
- Rotate every OAuth access token, refresh token, and client secret associated with any MCP server configured in the affected instance.
- Revoke and re-issue upstream credentials for any third-party service reachable through Onyx MCP integrations.
- Audit BASIC_ACCESS user activity against MCP endpoints for the entire exposure window.
Patch Information
The fix is delivered in commits 3f3d79d, 4001cedd, and b1039378, consolidated in pull requests #11238, #11242, and #11243. See the GitHub Security Advisory GHSA-q62f-rv3h-f822 and the GitHub Release v4.0.0 for full release notes.
Workarounds
- If patching is not immediately possible, disable MCP server integrations by removing configured MCP servers from the Onyx admin console.
- Restrict network access to /api/mcp/servers* routes via a reverse proxy allowlist limited to admin operators.
- Temporarily suspend BASIC_ACCESS account issuance and review existing accounts for unexpected activity.
# Verify running Onyx version and confirm patched build
docker exec onyx-backend python -c "import onyx; print(onyx.__version__)"
# Example reverse-proxy allowlist (nginx) to gate MCP routes until patched
# location ~ ^/api/mcp/servers {
# allow 10.0.0.0/24; # admin network only
# deny all;
# proxy_pass http://onyx-backend;
# }
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

