Skip to content

Open authentication bypass in MCP middleware #3076

@Deeven-Seru

Description

@Deeven-Seru

Summary

A critical authentication bypass exists in internal/server/server.go within mcpAuthMiddleware. If an external Authorization Server using generic opaque tokens experiences an outage, timeout, or DNS failure (Code: 500), the middleware fails open, granting an unauthenticated attacker full access to the MCP SSE session and backend tools.

Technical Details

In internal/server/server.go:mcpAuthMiddleware, the authorization error is handled using a switch statement over mcpErr.Code:

if err := mcpSvc.ValidateMCPAuth(r.Context(), r.Header); err != nil {
	var mcpErr *generic.MCPAuthError
	if errors.As(err, &mcpErr) {
		switch mcpErr.Code {
		case http.StatusUnauthorized:
			// Returns 401
			return
		case http.StatusForbidden:
			// Returns 403
			return
		}
	}
	// BUG: Exits the if block and unconditionally falls through!
}
next.ServeHTTP(w, r)

If an attacker deliberately sends a fake opaque token and the external introspection endpoint fails or times out, ValidateMCPAuth returns an *MCPAuthError with Code: http.StatusInternalServerError. The switch statement misses the 500 HTTP status code, exits the error block, and immediately calls next.ServeHTTP(w, r). This completely bypasses authentication and allows the unauthenticated request to proceed.

Impact

  • Fail-Open Authentication Bypass: Unauthenticated actors can bypass security checks if the introspection server is temporarily degraded or offline.
  • Privilege Escalation: Allows unauthorized external actors to execute internal database tools (SQL querying, BigQuery execution, etc.) without valid tokens.
  • Exploitability: Attackers can actively trigger this by performing an HTTP/DNS DoS against the Authorization Server, forcing a 500 introspection error, and subsequently unlocking the Toolbox framework.

Recommended Mitigation

Change mcpAuthMiddleware to fail-closed immediately by applying a default case in the switch block, and a catch-all http.Error for any non-MCPAuthError standard errors:

		default:
			http.Error(w, mcpErr.Message, mcpErr.Code)
			return
		}
	}
	http.Error(w, "Internal Server Error during authentication", http.StatusInternalServerError)
	return
}
next.ServeHTTP(w, r)

CC: @averikitsch @Yuan325

Metadata

Metadata

Assignees

Labels

priority: p2Moderately-important priority. Fix may not be included in next release.status: help wantedStatus: Unplanned work open to contributions from the community.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions