vMCP: session identity binding is not enforced for `tools/list` (and other list methods)
I maintainer di solito rispondono entro 1 giorno
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 22/100
- Tipo di issue
- Bug
- Chiarezza
- Abbastanza chiara
- Stato di attività
- Attiva
- Stack tecnologico
- go, kubernetes
- Ambito
- authorization, security
Direzione di ricerca
Start in pkg/vmcp/session/internal/security/security.go, where sessionBindingDecorator overrides only CallTool, ReadResource and GetPrompt and delegates the list methods to the embedded MultiSession. Done means tools/list, resources/list, resources/templates/list and prompts/list reject a foreign caller with the same error as tools/call. Linked PR #6788 is already open, so check it first and coordinate before starting.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Summary
vMCP binds each MCP session to the identity that created it and rejects calls from a different identity (identity binding mismatch → caller identity does not match session owner → session terminated). This works as intended for tools/call.
However, tools/list on a foreign session is answered with HTTP 200 and the session owner's tool list. A caller with a valid token of a different user can therefore enumerate the tools (and thereby the backends/permissions) of another user's session, provided they know its Mcp-Session-Id.
Environment
- ToolHive operator / vMCP v0.51.4 (Kubernetes,
VirtualMCPServer) - Embedded auth server with upstream providers (Keycloak as primary, a second OAuth provider via
upstreamInject), Redis session storage, 2 vMCP replicas - Cedar authorization (
MCPAuthzConfig) with per-group tool policies: user A is allowed 16 tools, user B 13 tools
Steps to reproduce
- User A logs in (OAuth via the embedded auth server), sends
initialize, receivesMcp-Session-Id: S. - User B logs in separately and obtains their own valid access token.
- User B sends
tools/listwith their ownAuthorization: Bearer <token B>andMcp-Session-Id: S. - User B sends
tools/call(any allowed read-only tool) with the same headers.
Observed
- Step 3: HTTP 200, 16 tools – the list of user A, including tools from backends user B is not authorized for (B's own session lists 13).
- Step 4: rejected. Log:
WARN identity binding validation failed: identity binding mismatch reason=identity_binding_mismatch WARN caller authorization failed, terminating session capability=<tool> error="caller identity does not match session owner" INFO Manager.Terminate: session terminated - Afterwards user A's session is terminated (A gets 0 tools / errors and must re-initialize).
Expected
tools/list (and presumably resources/list, resources/templates/list, prompts/list) should validate the caller against the session binding just like tools/call, and reject a foreign caller before returning any session-scoped data.
Analysis
pkg/vmcp/session/internal/security/security.go: sessionBindingDecorator only overrides CallTool, ReadResource and GetPrompt; all other methods are delegated to the embedded MultiSession without validation (documented in the type comment). The list handlers therefore return the owner's session-scoped capabilities (which, with Cedar, are already filtered per user) to any authenticated caller.
Impact
Low to moderate: requires a valid token and the victim's session ID (random UUID, only transmitted in headers). No tool results or identity data are leaked; only tool names / descriptions / schemas of the owner's session. With per-user authorization this reveals which backends and tools another user may use.
Related observation (by design, mentioned for completeness): a foreign tools/call terminates the owner's session (terminateOnBindingFailure, hijack prevention). Combined with the missing check on list methods, it might be worth rejecting foreign callers consistently at the session lookup for all methods, so that the behaviour is the same regardless of the method used. Whether termination of the owner's session is the desired trade-off (vs. just rejecting the foreign request) could be reconsidered.
Possible fix
Validate the caller binding for the list methods as well (e.g. in the decorator or centrally when resolving the session for any request), returning the same error as for tools/call.
- Lingua principale
- Go
- Stelle
- 2.3k
- Fork
- 318
- Merge medio
- 2g 1h
- PR unite (30g)
- 84
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di stacklok/toolhive
-
bug needs-triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 1 giorno
-
proxyrunner tool-filter middleware strips SEP-2322 Modern envelope from tools/list, breaking vMCP health checksForse già presa @alex-feel l’ha presa 25 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
stacklok/toolhive#6684 · 5 commenti · 1 reazione · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
HttpClientBuilder.Build() ignores HTTP(S)_PROXY (auth-server OAuth/DCR calls bypass forward proxy)Forse già presa @schonmann l’ha presa 16 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
stacklok/toolhive#6671 · 2 commenti · 1 reazione · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
`thv run` ignores `--oidc-insecure-allow-http` and `--thv-ca-bundle` — both dropped in `createOIDCConfig` (same as #1470)Forse già presa @7487 l’ha presa 42 giorni fa. Apertaauthentication bug cli oidc p1
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
stacklok/toolhive#6522 · 4 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Redis user-keyed upstream token read does not verify row ownershipForse già presa @hellouz818 l’ha presa 4 giorni fa. Apertaneeds-triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di stacklok/toolhive
Issue simili
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 2 giorni
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 83/100
devlikeapro/waha#2322 ·
I maintainer di solito rispondono entro 2 giorni
-
validateDeclaredPath lets control characters through into the Gradle init script's Groovy literalApertaagent-butler-finding agent-research bug ready-for-agent
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
jordansmall/spindrift#5821 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
I maintainer di solito rispondono entro 1 giorno
-
[rmqctl][Bug] Windows build script fails when the output directory is absentForse già presa Una pull request collegata a questa issue è aperta o già unita. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
apache/rocketmq-dashboard#7243 ·
I maintainer di solito rispondono entro 3 giorni