Sep 19, 2026·8 min read·3 visits
ToolHive failed to isolate local containerized MCP servers by default, allowing malicious containers to bypass isolation via host.docker.internal and access unauthenticated host-local APIs and databases.
A high-severity access control vulnerability in ToolHive CLI before v0.30.1 and ToolHive Studio before v0.38.0 allows local containerized MCP servers to bypass network isolation. This enables malicious workloads to establish TCP/IP connections to administrative and control plane endpoints exposed on the host loopback interface.
ToolHive is an orchestration framework designed to deploy and manage Model Context Protocol (MCP) servers, which allow Large Language Models (LLMs) to interact with external tools, APIs, and file systems. To run these tools safely, ToolHive supports running MCP servers inside containerized environments. The containerization model is intended to provide a security boundary, preventing untrusted or compromised MCP servers from accessing sensitive files or network assets hosted on the parent machine.
The vulnerability designated as CVE-2026-58197 represents a failure to enforce this isolation boundary. Prior to ToolHive CLI version 0.30.1 and ToolHive Studio version 0.38.0, the network configuration of these containers was left wide open by default. The platform allowed containerized applications to resolve and route network traffic directly back to the host machine through standard Docker virtual network paths, such as the host bridge gateway.
This architectural flaw exposes a significant attack surface. Because ToolHive's administrative control plane, local proxy configurations, and other adjacent microservices listen on localhost without requiring authentication, any containerized MCP server can communicate back to these interfaces. This vulnerability bypasses the intended sandbox, facilitating lateral movement from an isolated container to the broader host operating system.
The root cause of CVE-2026-58197 lies in an insecure default configuration combined with an implicit type conversion characteristic of the Go programming language. When ToolHive's backend API parses incoming JSON payloads to configure workload executions, it deserializes the payload into structure definitions. In Go, when a primitive type such as a boolean is omitted from a JSON string, the json.Unmarshal process automatically assigns the type's zero-value, which is false.
The structure defining the update request was modeled using a standard primitive boolean: NetworkIsolation bool. Because of this design choice, any client payload that omitted the network_isolation key would automatically cause the application to initialize the field to false. Instead of interpreting the absence of the key as an instruction to apply a secure-by-default profile, the application silently disabled network isolation. This left containers attached to the standard bridge network with full egress access to the host bridge interface.
Furthermore, ToolHive Studio, the graphical interface wrapper, contained a front-end implementation error where it explicitly transmitted "network_isolation": false in its payload structures. Even if a user intended to run an isolated container, the client application explicitly overrode this preference, sending a negative flag value to the API. This combination of unsafe JSON deserialization defaults in the CLI and explicit disabling in the GUI meant that almost all local container workloads ran without active network restrictions. Consequently, containerized processes could resolve DNS records like host.docker.internal and establish connections directly to ports listening on the host's loopback interface.
To understand the precise vulnerability mechanics, we must analyze the Go payload definition and the subsequent remediation. In the vulnerable implementation of the Go backend, the updateRequest struct in pkg/api/v1/workload_types.go used a raw boolean type. This made it impossible to distinguish between a client that explicitly requested isolation to be disabled and a client that omitted the field entirely.
// VULNERABLE STRUCT DEFINITION
type updateRequest struct {
ProxyMode string `json:"proxy_mode"`
// If this field is omitted from the JSON request payload,
// Go unmarshals it to its zero-value (false), disabling isolation.
NetworkIsolation bool `json:"network_isolation"`
}The remediation resolved this ambiguity by changing the field type to a pointer to a boolean (*bool). When unmarshaling JSON, an omitted field is mapped to nil, while an explicit boolean value maps to a pointer containing true or false. This allows the application logic to identify omitted fields and safely apply a secure-by-default logic gate.
// PATCHED STRUCT DEFINITION
type updateRequest struct {
ProxyMode string `json:"proxy_mode"`
// Pointer type allows distinguishing between nil (omitted) and false
NetworkIsolation *bool `json:"network_isolation,omitempty"`
}
// Helper function to resolve the boolean value with a secure default
func networkIsolationEnabled(v *bool) bool {
// If the field is omitted (nil), default to secure network isolation (true)
if v == nil {
return true
}
return *v
}In addition to this backend structural change, the CLI flag parser was updated in cmd/thv/app/run_flags.go to flip the default value of the network isolation parameter from false to true. This ensures that any command-line invocation that does not explicitly specify isolation parameters will run the container within an isolated network sandbox, closing the vulnerability for CLI users.
Exploitation of CVE-2026-58197 requires that a user deploy a malicious or compromised MCP server container. Since MCP servers are often downloaded from public repositories or third-party sources to perform tasks like text formatting, web scraping, or database querying, this constitutes a realistic vector. Once the user runs the container, the attacker-controlled code inside the container execution context initiates an automated reconnaissance scan against the Docker gateway IP.
The attack path progresses from the container namespace through the virtual bridge network to the host's IP space. In standard Docker configurations on macOS and Windows, host.docker.internal resolves to the IP address of the host machine. In Linux environments, the gateway interface (typically 172.17.0.1 or gateway.docker.internal) serves the same routing role. The script running inside the container attempts to establish TCP handshakes with sensitive local services listening on the host.
Because ToolHive's internal control plane endpoints are bound to the host's local loopback network interface without mandatory authentication tokens, the containerized process can invoke administrative commands. It can execute local HTTP POST requests to manage other containers, request sensitive credential payloads, extract environment variables, or execute arbitrary operations via other unisolated sibling MCP tools. The attacker achieves complete lateral movement and potential remote code execution on the host machine.
The security impact of this vulnerability is classified as high, receiving a CVSS v3.1 base score of 8.8. The primary risk lies in the complete compromise of the host's local environment. An attacker who successfully runs an MCP server container can interact with any service bound to localhost, effectively bypassing firewall rules that block external network access. This exposes developer workstations and internal build servers to critical risks.
Common local services that become vulnerable to compromise include local LLM engines such as Ollama, database servers, and development-stage Kubernetes APIs. By interacting with these interfaces, the malicious container can exfiltrate proprietary model weights, inject poison data into databases, or spin up unauthorized workloads. If the host machine has access to cloud provider metadata services or environment variables with cloud credentials, the attacker can leverage this access to compromise cloud environments.
Additionally, because ToolHive is designed to manage workloads, an attacker can manipulate the state of other deployed containers. By calling the administrative APIs on localhost, the malicious container can shut down security agents, spin up new malicious containers, or access logs containing high-value secrets. The failure to maintain container boundaries nullifies the core security benefit of containerized execution.
Remediation of CVE-2026-58197 requires updating both the ToolHive CLI and ToolHive Studio components to their patched releases. Administrators must deploy ToolHive CLI version 0.30.1 or later and ToolHive Studio version 0.38.0 or later. These versions incorporate the secure-by-default posture where the network isolation flag defaults to true, and empty API payloads default to enabling isolation.
In scenarios where immediate upgrades are not possible, administrators should implement manual workarounds. For CLI deployments, users must modify all execution scripts to explicitly include the isolation flag, overriding the insecure default. The command structure should be adjusted to: thv run --isolate-network=true <SERVER_NAME>. This ensures the container runtime configures restricted network namespaces.
For network-level protection, security teams can apply firewall configurations on the host machine. By defining rules in iptables or similar filtering utilities, hosts can block incoming traffic from Docker bridge subnets (typically 172.17.0.0/16) destined for sensitive local administrative ports. This defense-in-depth approach ensures that even if a container runs with an insecure network profile, the host operating system actively drops unauthorized connection attempts.
CVSS:3.1/AV:A/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
toolhive stacklok | < 0.30.1 | v0.30.1 |
toolhive-studio stacklok | < 0.38.0 | v0.38.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-284 / CWE-306 |
| Attack Vector | Adjacent Network (AV:A) |
| CVSS Base Score | 8.8 (High) |
| Exploit Status | No Public Exploit |
| CISA KEV Status | Not Listed |
| Impact | Privileged Host Access / Remote Code Execution via lateral APIs |
The software does not restrict or incorrectly restricts access to a resource from an unauthorized actor.
AnyCable is a real-time communication server. Prior to version 1.6.15, its Pusher-compatible REST API suffered from an authentication bypass vulnerability because it failed to verify that the request body matched the signature-validated body_md5 parameter. This allows attackers to perform replay attacks with modified body contents.
A denial-of-service vulnerability exists in AnyIO prior to version 4.14.2. Standard error streams of process-pool workers are connected to an operating system pipe that is never drained by the parent process. This allows a worker to fill the pipe buffer and deadlock indefinitely.
CVE-2026-63349 is a critical privilege-dropping bypass vulnerability in the AnyIO asynchronous framework (versions 4.14.0 and 4.14.1) on POSIX platforms. Due to a variable assignment typo, supplementary groups specified by the developer are not correctly propagated to the execution backend, resulting in subprocesses retaining the parent process's elevated supplementary group permissions.
CVE-2026-63406 is an information disclosure vulnerability in AnyCable-go prior to version 1.6.15. The built-in telemetry client is enabled by default with a hardcoded public authentication token ('secret'). This client digests highly sensitive configuration parameters and command-line arguments, including JWT secrets and RPC secrets, into a stable SHA-256 fingerprint. This fingerprint is sent over public networks, exposing those administrative secrets to offline dictionary and brute-force attacks if intercepted.
CVE-2026-84992 is a Cross-Site Scripting (XSS) vulnerability affecting md-editor-v3 before version 6.5.4. It occurs because the fenced-code block language parser directly interpolates unescaped language metadata into unquoted HTML attributes inside the custom rendering callback. This bypasses the built-in XSSPlugin which runs during the parsing phase, before rendering.
CVE-2026-81505 is a high-severity Broken Object Level Authorization (BOLA) / Insecure Direct Object Reference (IDOR) vulnerability in Convoy, a cloud-native webhooks gateway. In affected versions prior to 26.6.8, the single-item Source retrieval API endpoint authorizes project access but fails to confirm if the requested Source belongs to that specific project. This logical flaw allows authenticated users or project-scoped API key holders to bypass tenant isolation boundaries and retrieve unredacted, plaintext message broker credentials for Apache Kafka, Amazon SQS, RabbitMQ, and Google Cloud Pub/Sub belonging to other tenants. This issue is fully patched in version 26.6.8.