Skip to content

CVE-2026-58196: Verified Reproduction

CVE-2026-58196: ToolHive SSRF in remote MCP server authentication discovery

CVE-2026-58196 is verified against github.com/stacklok/toolhive · github. Affected versions: All ToolHive versions before 0.31.0. The GitHub repo advisory states ToolHive through v0.29.3 and main HEAD b672d82f41e6a919670ee1abe812f831ecb72448 were verified vulnerable before the fix. Vulnerability class: SSRF. This medium reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00290.

REPRO-2026-00290 github.com/stacklok/toolhive · github SSRF Known vulnerability Jul 16, 2026 CVE entry .txt
Severity
MEDIUM
Confidence
HIGH
Reproduced in
43m 47s
Tool calls
210
Spend
$12.99
01 · Overview

What Is CVE-2026-58196?

CVE-2026-58196 is a medium-severity server-side request forgery (CWE-918) in ToolHive before 0.31.0. During remote MCP server authentication discovery, the ToolHive host can be tricked into fetching an attacker-selected internal URL. Pruva reproduced it (reproduction REPRO-2026-00290).

02 · Severity & CVSS

CVE-2026-58196 Severity

CVE-2026-58196 is rated medium severity.

MEDIUM threat level
Weakness CWE-918 Server-Side Request Forgery — Server-Side Request Forgery (SSRF)

Medium — meaningful risk under specific conditions. Schedule a fix in the normal cycle.

03 · Affected Versions

Affected github.com/stacklok/toolhive Versions

github.com/stacklok/toolhive · github versions All ToolHive versions before 0.31.0. The GitHub repo advisory states ToolHive through v0.29.3 and main HEAD b672d82f41e6a919670ee1abe812f831ecb72448 were verified vulnerable before the fix. are affected.

How to Reproduce CVE-2026-58196

$ pruva-verify REPRO-2026-00290
or curl -O https://www.pruva.dev/api/v1/reproductions/REPRO-2026-00290/artifacts/bundle/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh
Run in a VM or disposable container. This exploits a real vulnerability.
06 · Proof of Reproduction

Proof of Reproduction for CVE-2026-58196

Security impact — reproduced
  • reached the target end-to-end
  • full exploit chain demonstrated
  • on the real production code path
  • high confidence
  • the upstream fix blocks the same trigger
Trigger

remote MCP WWW-Authenticate resource_metadata URL and metadata 302 Location header

Attack chain
  1. ToolHive CLI: thv run <malicious-remote-url> --remote-auth
Runnable proof: reproduction_steps.sh
Captured evidence: toolhive vulnerable attempt1malicious server vulnerable attempt1canary vulnerable attempt1canary fixed attempt1toolhive vulnerable attempt2toolhive fixed attempt1toolhive fixed attempt2malicious server vulnerable attempt2
How the agent worked 457 events · 210 tool calls · 44 min
44 minDuration
210Tool calls
100Reasoning steps
457Events
5Dead-ends
Agent activity over 44 min
Policy
1
Support
24
Repro
176
Variant
251
Verify
1
0:0043:47

Root Cause and Exploit Chain for CVE-2026-58196

Versions: all versions before 0.31.0. The reproduction uses ToolHive v0.30.0 as the vulnerable build and v0.31.0 as the fixed negative control.
  • Affected versions: all versions before 0.31.0. The reproduction uses ToolHive v0.30.0 as the vulnerable build and v0.31.0 as the fixed negative control.
  • Risk level and consequences: CWE-918 server-side request forgery. A malicious or compromised remote MCP server can cause the ToolHive host process, outside the intended per-server container isolation boundary, to fetch attacker-selected internal URLs. In a real deployment this can expose internal HTTP services or metadata endpoints reachable from the host.

Impact Parity

  • Disclosed/claimed maximum impact: host-side SSRF during remote MCP server authentication discovery.
  • Reproduced impact from this run: host-side HTTP GET from ToolHive v0.30.0 to an attacker-selected loopback canary URL after an attacker-controlled RFC 9728 resource_metadata endpoint issues a 302 redirect.
  • Parity: full.
  • Not demonstrated: no secrets were targeted or exfiltrated. The lab intentionally used a local canary and recorded only request path, headers, and redirect behavior.

Root Cause

In vulnerable ToolHive v0.30.0, FetchResourceMetadata(ctx, metadataURL) in pkg/auth/discovery/discovery.go constructs a normal http.Client for a server-supplied RFC 9728 resource metadata URL. That client has no CheckRedirect policy and no private/loopback/link-local dial guard. Therefore, after the remote MCP endpoint returns WWW-Authenticate: Bearer ... resource_metadata="<attacker URL>", ToolHive fetches the attacker metadata URL and automatically follows HTTP 30x redirects to a different host/port. This occurs in the host-side authentication discovery path, before/outside any per-server container sandbox.

The v0.31.0 fix changes the discovery clients to enforce redirect and private-address protections: DetectAuthenticationFromServer and metadata/OIDC discovery use networking.SameHostRedirectPolicy(), FetchResourceMetadata accepts a blockPrivateIPs setting, and the protected HTTP transports can use networking.NewPrivateIPBlockingDialContext(). The same-host redirect policy refuses redirects to a different host:port and HTTPS-to-HTTP downgrades, which prevents the demonstrated cross-port loopback canary request.

Reproduction Steps

  1. Run bundle/repro/reproduction_steps.sh.
  2. The script:
    • Uses the prepared project cache when available (<project_cache_dir>/repo and <project_cache_dir>/bin) and downloads exact ToolHive release binaries for v0.30.0 and v0.31.0 if not already cached.
    • Starts a malicious remote MCP HTTP endpoint and a separate loopback canary HTTP endpoint in a closed lab network.
    • Invokes the real product workflow twice per version: thv run <malicious-url> --remote-auth --remote-auth-skip-browser --foreground.
    • The malicious MCP endpoint returns a WWW-Authenticate header with an attacker-controlled resource_metadata URL. That metadata endpoint returns a 302 redirect to the separate canary.
    • Records per-attempt ToolHive, malicious endpoint, and canary logs under bundle/logs/, and writes bundle/repro/runtime_manifest.json before exit.
  3. Expected evidence:
    • ToolHive v0.30.0: both vulnerable attempts reach the malicious endpoint and the canary receives one ToolHive host-side request per attempt.
    • ToolHive v0.31.0: both fixed attempts reach the malicious endpoint but the canary remains untouched.

Evidence

  • Main run log: bundle/logs/reproduction_steps.log
    • Shows two vulnerable successes and two fixed negative controls:
      • vulnerable attempt 1: malicious requests=6, canary requests=1
      • vulnerable attempt 2: malicious requests=6, canary requests=1
      • fixed attempt 1: malicious requests=6, canary requests=0
      • fixed attempt 2: malicious requests=6, canary requests=0
      • [CONFIRMED] CVE-2026-58196 reproduced with vulnerable/fixed divergence.
  • Vulnerable ToolHive product log: bundle/logs/toolhive_vulnerable_attempt1.log
    • Confirms the real thv run remote MCP workflow and host-side discovery path:
      • Attempting to run remote MCP server: http://127.0.0.1:<port>
      • Detected authentication requirement from server with resource_metadata set to the attacker endpoint.
      • Fetching resource metadata for that attacker URL.
  • Malicious endpoint log: bundle/logs/malicious_server_vulnerable_attempt1.log
    • Records the initial ToolHive request to /, the RFC 9728 metadata redirect at /metadata-redirect/vulnerable/1, and the redirect location pointing at the separate canary URL.
  • Canary log: bundle/logs/canary_vulnerable_attempt1.log
    • Records the vulnerable host-side SSRF oracle:
      • method: GET
      • path: /internal-canary/vulnerable/1/metadata.json
      • Referer: http://127.0.0.1:<malicious-port>/metadata-redirect/vulnerable/1
      • User-Agent: Go-http-client/1.1
  • Fixed product logs: bundle/logs/toolhive_fixed_attempt1.log, bundle/logs/malicious_server_fixed_attempt1.log, and bundle/logs/canary_fixed_attempt1.log
    • The fixed build reaches the malicious remote endpoint but the corresponding canary log stays empty, demonstrating the v0.31.0 redirect/private-dial protection blocks the canary fetch.
  • Structured evidence manifest: bundle/repro/runtime_manifest.json.
  • Attempt summary: bundle/artifacts/toolhive-ssrf/attempts.jsonl.

Recommendations / Next Steps

  • Upgrade ToolHive to v0.31.0 or later.
  • Keep same-host redirect restrictions and private/loopback/link-local dial blocking on every HTTP client that fetches URLs derived from remote MCP server responses, including RFC 9728 metadata, OIDC discovery, and dynamic client registration discovery.
  • Add regression tests for: resource_metadata redirects to different host/port, redirects from public targets to private/loopback/link-local addresses, HTTPS-to-HTTP downgrade redirects, and DNS/private-IP rebinding during discovery.
  • Ensure future remote discovery features explicitly distinguish operator-configured trusted URLs from server-supplied URLs and apply stricter SSRF guards to the latter.

Additional Notes

  • Idempotency confirmation: bundle/repro/reproduction_steps.sh was run twice consecutively after finalization and succeeded both times with the same vulnerable/fixed divergence.
  • The lab does not contact real cloud metadata or third-party services. It uses a local malicious endpoint and a local canary as a safe stand-in for an internal service.
  • The script attempts to bind a public-looking lab address for the remote endpoint, but if the sandbox cannot add/bind that address it falls back to loopback. The fixed-version negative control remains valid because v0.31.0 refuses the cross-host/cross-port redirect before the canary request is made.

CVE-2026-58196 Reproduction Transcript

The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired. Phases: support · claim contract · reproduction · judge · variant analysis

Full session Replay every step — scrub the timeline or play it back.

Event 1/40
0:002:20
0:00
session startedgpt-5.5 · CVE-2026-58196 · REPRO-20
0:06
0:11
web search
0:17
0:18
0:19
0:20
web search
0:28
0:28
0:29
0:31
web search
0:40
web search
0:44
0:57
web search
1:02
1:47
extract_facts
no facts extracted
1:50
1:52
1:52
supportclaim_contract
1:59
1:59
1:59
2:02
2:13
2:13
2:13
2:14
web search
08 · How to Fix

How to Fix CVE-2026-58196

Coming soon

Step-by-step mitigation and hardening guidance for CVE-2026-58196 — configuration checks, workarounds where no patch exists, and how to verify you're protected — is on the way.

10 · FAQ

FAQ: CVE-2026-58196

Is the CVE-2026-58196 SSRF in the container sandbox or the host?

It is in the ToolHive HOST process, not the per-server container sandbox. The host-side discovery flow (pkg/auth/discovery and pkg/auth/remote, invoked by the CLI remote-server workflow) is what follows the attacker-influenced redirect, bypassing the intended container isolation.

Which versions of ToolHive are affected by CVE-2026-58196?

All ToolHive versions before 0.31.0 are affected. Pruva used v0.30.0 as the vulnerable build and v0.31.0 as the fixed negative control, which blocks the cross-host/cross-port redirect.

How severe is CVE-2026-58196?

It is rated medium severity. It requires a user to onboard a malicious or compromised remote MCP endpoint, but when that happens the host can be steered to fetch attacker-chosen internal URLs.

How can I reproduce CVE-2026-58196?

Download the verified script from this page and run it in an isolated environment against ToolHive v0.30.0. A crafted remote MCP endpoint returns a resource_metadata redirect to a loopback canary; the vulnerable host follows it, and v0.31.0 blocks it.
11 · References

References for CVE-2026-58196

Authoritative sources for CVE-2026-58196 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.