# Your MCP Server Is Listening on 0.0.0.0 and Accepting Anonymous Client Registrations

> Source: <https://dev.to/numbpill3d/your-mcp-server-is-listening-on-0000-and-accepting-anonymous-client-registrations-21fh>
> Published: 2026-09-26 08:01:14+00:00

Bifrost is an open-source AI gateway that sits between your application and your LLM providers. It handles routing, load balancing, and fallback logic for models from OpenAI, Anthropic, Google, and about a dozen others. It also speaks MCP, the Model Context Protocol, which means it can register and manage tool-providing clients as part of the AI agent stack. Thousands of teams use it. The official Docker image ships with management authentication disabled and the API bound to `0.0.0.0`. One unauthenticated POST to `/api/mcp/client` gets you a shell.

CVE-2026-90898. CVSS 9.8. Discovered by Yuval Moravchick at JFrog Security Research. Patched in transports/v2.1.0. If you're running anything in the 2.0.x or 1.6.x lines, your MCP management API is accepting anonymous client registrations right now.

MCP supports multiple transport types. The one that matters here is stdio: a client type that launches a local subprocess and communicates with it over standard input/output. When you register a stdio MCP client through Bifrost's management API, the gateway spawns the specified command as its own process user.

The stock Bifrost binary binds the management API to `localhost` by default. Limited exposure. The official Docker image overrides this to `0.0.0.0`, because containers need to accept connections from outside their network namespace. If you published the management port in your `docker-compose.yml`, which you probably did because the documentation shows you how, the API is now reachable from anywhere that can route to your host.

Management authentication is disabled by default. The setting is `governance.auth_config.is_enabled`, and it defaults to `false`. The attack requires exactly one HTTP request.

An attacker sends a POST to `/api/mcp/client` with a JSON body specifying a stdio-type connection:

```
{
  "connection_type": "stdio",
  "auth_type": "none",
  "stdio_config": {
    "command": "/bin/sh",
    "args": ["-c", "id && cat /etc/passwd && env"],
    "tools_to_execute": ["*"]
  }
}
```

Bifrost spawns `/bin/sh` immediately. It doesn't wait for the MCP handshake to complete. The HTTP request eventually times out because the spawned process isn't speaking MCP protocol back, but the command has already executed. The shell ran as `appuser`, which is the default user in the Bifrost Docker image.

That `env` at the end of the command chain is the important part. In a running Bifrost instance, environment variables contain API keys for every connected LLM provider: OpenAI, Anthropic, Google, Cohere, whatever you've configured. One request, arbitrary command execution, and your entire provider key set exfiltrated.

This is the third significant MCP-related vulnerability in the past month. On September 6, Bifrost itself caught a separate flaw (CVE-2026-86242, CVSS 8.1). On September 14, the broader MCP ecosystem was dealing with tool description injection attacks where malicious tool metadata could manipulate agent behavior. And that's just the named CVEs. The protocol's attack surface is expanding faster than the security model can keep up.

The fundamental problem: MCP has no client authentication story. The protocol defines tool providers and tool consumers, but the registration mechanism for new clients is left to the transport implementation. Bifrost's implementation was "accept the POST and spawn the process." No token, no certificate, no challenge. The fix in transports/v2.1.0 returns a 403 for unauthenticated stdio registration, which is the right answer, but it's a patch on a design gap.

If you're deploying MCP-enabled infrastructure in production, your security posture depends on every gateway, proxy, and transport layer having independently implemented client authentication correctly. There's no protocol-level guarantee. Every implementation is rolling its own auth story, and some of them are rolling "none."

Teams running persistent agent deployments with frameworks like those covered in the [OpenClaw Automation Bible](https://numbpilled.gumroad.com/l/openauto) should audit every MCP endpoint in their stack. The YAML configs that define your agent topology are also your attack surface map. If a config specifies a stdio transport, the underlying gateway better require authentication before spawning anything.

If you're running Bifrost in Docker, check your compose file first:

```
# Vulnerable: management port published, auth disabled
services:
  bifrost:
    image: bifrost-ai/bifrost:2.0.0
    ports:
      - "8080:8080"  # Management API exposed
    environment:
      - BIFROST_AUTH_ENABLED=false  # Default
```

Test whether the management API is reachable:

``` bash
$ curl -s http://your-bifrost-host:8080/health
# If this returns 200, the management API is accessible
```

Check the version:

``` bash
$ curl -s http://your-bifrost-host:8080/api/version
# Anything below transports/v2.1.0 is vulnerable
```

If you can't upgrade immediately, enable authentication:

```
governance:
  auth_config:
    is_enabled: true
    admin_username: "admin"
    admin_password: "something-that-isnt-the-default"
```

And restrict the management listener to trusted networks. If you're behind a reverse proxy, don't expose port 8080 at all. The management API should never face the internet.

If your Bifrost instance was internet-facing with authentication disabled for any period, assume compromise. The remediation sequence:

`/api/mcp/client`.` appuser` account in Docker has limited privileges, but depending on your container configuration, an attacker may have written to mounted volumes or established outbound connections.

``` bash
# Search for suspicious MCP client registration attempts
$ docker logs bifrost 2>&1 | grep -i "mcp/client"

# Check for unexpected outbound connections during the exposure window
$ docker logs bifrost 2>&1 | grep -E "(curl|wget|nc |ncat)"
```

The MCP ecosystem is moving fast. New gateways, new transport implementations, new client libraries, all shipping features faster than they're shipping security reviews. Bifrost is open-source, well-maintained, and had JFrog's security research team actively looking at it. They still shipped a CVSS 9.8 in their default Docker configuration.

The uncomfortable question for anyone running MCP in production: if a maintained, actively-audited gateway shipped with authentication disabled and the management API bound to all interfaces, what's lurking in the smaller, less-scrutinized MCP implementations in your stack?

Every MCP transport endpoint is a registration surface. Every registration surface that accepts unauthenticated requests is a shell waiting to happen. The protocol doesn't enforce this boundary. Your infrastructure has to.

If you want a framework for building and securing persistent agent deployments, including the MCP transport hardening that the protocol itself doesn't give you, I put together a production-focused system at [numbpilled.gumroad.com](https://numbpilled.gumroad.com/l/paperclip-claude-method) covering the full agent lifecycle from deployment through operational security.

*Written with AI assistance. Technical content, methodology, and voice are mine.*
