{"slug": "your-mcp-server-is-listening-on-0-0-0-0-and-accepting-anonymous-client", "title": "Your MCP Server Is Listening on 0.0.0.0 and Accepting Anonymous Client Registrations", "summary": "JFrog Security Research disclosed CVE-2026-90898, a CVSS 9.8 flaw in the open-source Bifrost AI gateway that lets an unauthenticated attacker achieve remote command execution by POSTing a stdio-type MCP client registration to the management API, which the official Docker image binds to 0.0.0.0 with authentication disabled by default. Because Bifrost spawns the specified command immediately without waiting for an MCP handshake, a single request can run shell commands as appuser and exfiltrate environment variables containing API keys for every connected LLM provider. The issue is patched in transports/v2.1.0, which returns 403 for unauthenticated stdio registration, though the researcher notes MCP itself defines no client authentication mechanism.", "body_md": "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.\n\nCVE-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.\n\nMCP 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.\n\nThe 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.\n\nManagement 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.\n\nAn attacker sends a POST to `/api/mcp/client` with a JSON body specifying a stdio-type connection:\n\n```\n{\n  \"connection_type\": \"stdio\",\n  \"auth_type\": \"none\",\n  \"stdio_config\": {\n    \"command\": \"/bin/sh\",\n    \"args\": [\"-c\", \"id && cat /etc/passwd && env\"],\n    \"tools_to_execute\": [\"*\"]\n  }\n}\n```\n\nBifrost 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.\n\nThat `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.\n\nThis 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.\n\nThe 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.\n\nIf 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.\"\n\nTeams 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.\n\nIf you're running Bifrost in Docker, check your compose file first:\n\n```\n# Vulnerable: management port published, auth disabled\nservices:\n  bifrost:\n    image: bifrost-ai/bifrost:2.0.0\n    ports:\n      - \"8080:8080\"  # Management API exposed\n    environment:\n      - BIFROST_AUTH_ENABLED=false  # Default\n```\n\nTest whether the management API is reachable:\n\n``` bash\n$ curl -s http://your-bifrost-host:8080/health\n# If this returns 200, the management API is accessible\n```\n\nCheck the version:\n\n``` bash\n$ curl -s http://your-bifrost-host:8080/api/version\n# Anything below transports/v2.1.0 is vulnerable\n```\n\nIf you can't upgrade immediately, enable authentication:\n\n```\ngovernance:\n  auth_config:\n    is_enabled: true\n    admin_username: \"admin\"\n    admin_password: \"something-that-isnt-the-default\"\n```\n\nAnd 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.\n\nIf your Bifrost instance was internet-facing with authentication disabled for any period, assume compromise. The remediation sequence:\n\n`/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.\n\n``` bash\n# Search for suspicious MCP client registration attempts\n$ docker logs bifrost 2>&1 | grep -i \"mcp/client\"\n\n# Check for unexpected outbound connections during the exposure window\n$ docker logs bifrost 2>&1 | grep -E \"(curl|wget|nc |ncat)\"\n```\n\nThe 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.\n\nThe 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?\n\nEvery 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.\n\nIf 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.\n\n*Written with AI assistance. Technical content, methodology, and voice are mine.*", "url": "https://wpnews.pro/news/your-mcp-server-is-listening-on-0-0-0-0-and-accepting-anonymous-client", "canonical_source": "https://dev.to/numbpill3d/your-mcp-server-is-listening-on-0000-and-accepting-anonymous-client-registrations-21fh", "published_at": "2026-09-26 08:01:14+00:00", "updated_at": "2026-09-26 08:30:25.686915+00:00", "lang": "en", "topics": ["ai-agents", "agent-protocols", "ai-infrastructure", "ai-tools"], "entities": ["Bifrost", "JFrog Security Research", "Yuval Moravchick", "Model Context Protocol", "OpenAI", "Anthropic", "Google", "Cohere"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/your-mcp-server-is-listening-on-0-0-0-0-and-accepting-anonymous-client", "markdown": "https://wpnews.pro/news/your-mcp-server-is-listening-on-0-0-0-0-and-accepting-anonymous-client.md", "text": "https://wpnews.pro/news/your-mcp-server-is-listening-on-0-0-0-0-and-accepting-anonymous-client.txt", "jsonld": "https://wpnews.pro/news/your-mcp-server-is-listening-on-0-0-0-0-and-accepting-anonymous-client.jsonld"}}