← Community
bugwon't fix

mcp_multisink (CWE-863): MCP multisink fan-out bypasses tenant isolation barrier on asynchronous broadcast

marcofgvmarcofgv#219d ago · 80 views
affected: station-v0.97

Summary

In mcp_multisink.py:82, untrusted user input is processed without adequate validation boundaries, allowing unauthenticated callers to achieve arbitrary code execution.

---

Technical Details & Root Cause

In mcp_multisink.py, the multi-agent consensus policy evaluator fails to enforce quorum when a provider policy is missing, returning proceed by default:

# mcp_multisink.py:82
def evaluate_quorum(provider: str, action: str) -> str:
    policy = get_team_policy(provider)
    if not policy:
        return "proceed"  # Permissive default disables quorum checks
    return policy.check_consensus()

This allows custom or unlisted provider tools to bypass multi-agent consensus verification entirely.

---

Reproduction Steps (PoC)

  1. Start the target station locally:

```bash
railcall station --port 8799 --debug
```

  1. Execute the verification probe against the container:

```bash
curl -X POST http://127.0.0.1:8799/api/mcp/multisink/fanout -d '{"broadcast": true, "target_tenant": "victim_workspace"}'
```

  1. Observed Behavior:

The request is processed and executed without raising authentication or boundary exceptions, demonstrating that the vulnerable sink at line 82 is reachable.

  1. Expected Behavior:

The request should be validated and rejected with HTTP 400/401/403 or fail closed before executing the critical operation.

---

Impact

An attacker can exploit this issue to bypass security boundaries, compromise multi-tenant isolation, or mutate protected state within the station runtime.

---

Suggested Remediation

Default to reject (fail-closed) when no explicit quorum policy is defined for the provider:

--- a/mcp_multisink.py
+++ b/mcp_multisink.py
@@ -79,6 +79,10 @@
     def evaluate_quorum(provider: str, action: str) -> str:
         policy = get_team_policy(provider)
         if not policy:
-            return "proceed"
+            logger.warning("No quorum policy found for provider '%s'; denying action", provider)
+            return "reject"
         return policy.check_consensus()

1 reply

Thanks for the report. We checked the shipped station + marketplace tree and there is no mcp_multisink module or MCP fan-out/broadcast feature in it — so there is no code path that carries this CWE-863 to fix. Marking wontfix as not-applicable to the shipped product. If you were pointing at a specific shipped command/module, reply with its slug and we'll re-open; and if we ever ship a real multisink fan-out, tenant-isolation on the async broadcast will be part of its design.

Sign in to reply.