stacklok / stacklok/toolhive

security: proxy forwards malformed upstream JSON-RPC frames to clients without validation

Open
#5,247 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Go
Stars
2.2k
Forks
300
Avg merge
1d 15h
Merged PRs (30d)
184

Description

Summary

The transparent proxy (thv run) forwards upstream MCP server responses to clients without validating JSON-RPC structure. When an upstream server returns a malformed frame — missing jsonrpc field, invalid id type, non-object body — the proxy passes it through with HTTP 200 rather than returning a structured error.

Why the proxy should validate

The proxy sits between untrusted upstream MCP servers and trusted clients. An attacker who controls an upstream server (supply chain compromise, misconfigured registry, prompt injection redirecting to a malicious server) can send malformed frames that:

  • Crash MCP clients that validate JSON-RPC strictly
  • Cause clients to misinterpret responses and act on garbage data
  • Trigger undefined behaviour in client-side JSON parsers

The MCP spec (JSON-RPC 2.0) requires responses to contain "jsonrpc": "2.0" and a valid id. A proxy that silently forwards protocol violations provides weaker security guarantees than one that rejects them at the boundary.

Observed behaviour

The transparent proxy reads the upstream HTTP response and writes it to the client unchanged — including HTTP status and body — with no JSON-RPC structural validation.

Reproduction: Start thv proxying a server that returns:

{"id": "not-an-integer", "result": {"broken": true}}

(missing "jsonrpc" field; id is a string, not an integer or null)

The proxy returns HTTP 200 with that body to the client.

Expected behaviour

The proxy should detect structurally invalid JSON-RPC responses from upstream and return a structured error (HTTP 400 or a JSON-RPC error object) to the client rather than forwarding the malformed frame.

Suggested fix

Add upstream response validation in the transparent proxy's response handling path. For JSON responses, verify the presence of "jsonrpc": "2.0" and that id is a string, number, or null before forwarding. Return a structured JSON-RPC error to the client when validation fails.

Discovered via DAST scanning in stacklok/stacklok-enterprise-platform.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the transparent proxy response-handling path used by thv run and trace how upstream HTTP responses are copied to clients. Reproduce the malformed JSON-RPC body from the issue, then verify that frames lacking jsonrpc: "2.0" or containing an invalid id are rejected with a structured error rather than forwarded with HTTP 200.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
api, backend, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
50/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.