ctipilot.ch
← Back to the live brief
HIGHCVE-2026-59726NATOB1vulnerability

CVE-2026-59726 (RufRoot) — Ruflo's MCP bridge took unauthenticated tool calls on all interfaces, and the memory it poisons is not cleaned up by the patch (CVSS 10.0)

discovered 2026-07-30 05:08 UTCrun 2026-07-30T0409Z-intel2 sourcesmulti-source

Ruflo is an open-source AI agent orchestration platform that ships a chat interface, agent swarms, persistent memory and Model Context Protocol tool calling. Noma Labs describes the exposed surface as the platform's MCP bridge, the Express.js server handling every tool invocation, and its finding is blunt about the prerequisite: "a single unauthenticated HTTP POST request to port 3001 gave full command execution inside the container. No token, no API key, no header check, no IP allowlist. Nothing" (Noma Security, 2026-07-29). The flaw carries a CVSS base score of 10.0, and the maintainer's own advisory describes the same path: before 3.16.3 the default Docker Compose deployment exposed the bridge's tool-invocation endpoints without authentication, letting an unauthenticated network caller reach the terminal-execution tool, obtain a shell in the bridge container, read provider API keys, and write into the agent's learning-store patterns (Ruflo, 2026-07-01).

What turns this from a configuration mistake into a shipped default is the packaging. Noma states that "the docker-compose.yml binds port 3001 to 0.0.0.0 by default, exposing the bridge on all network interfaces" (Noma Security, 2026-07-29). An operator who followed the project's own quickstart and never made a deliberate decision to publish the service still had it listening — which is why the exposure question here is not "did we open a port" but "did we run the supplied compose file".

Three consequences follow from one request, and they escalate in how hard they are to reverse. Command execution inside the bridge container is the immediate one. Reading the provider API keys the platform holds is the second, and those credentials are valid outside the compromised host — they buy inference spend and, depending on the account, access to whatever else the key authorises. The third is the one that outlives the incident: instructions written into the agent's persistent memory continue steering the platform's behaviour for later users. The maintainer's advisory is explicit about the remediation consequence — "audit the AgentDB pattern store for injected agentdb_pattern-store entries; purge poisoned patterns. A patched redeploy alone does NOT undo poisoning" (Ruflo, 2026-07-01).

That last property is the reason this is worth handling out of cycle even though the fix has been available since early July and nothing is reported exploited. Ordinary patch hygiene assumes the update restores a known-good state. Here the authentication bypass closes and the memory contents persist, so an instance that was reachable during the exposure window comes back up patched and still carrying whatever was planted in it. The fix in 3.16.3 changes the defaults — an explicit authentication-token environment variable is now required before the bridge binds publicly, and the terminal-execution tool needs its own separate opt-in — but neither change inspects existing memory.

Noma Labs states it "disclosed responsibly, and within a few hours, Ruflo had a full fix merged" (Noma Security, 2026-07-29), with the maintainer's advisory published 2026-07-01 (Ruflo, 2026-07-01). Noma published both the single unauthenticated request that reaches code execution and the full eight-step impact chain it built on top of it (Noma Security, 2026-07-29) — nothing here requires reconstruction effort from a reader.

Detection is straightforward where the telemetry exists, because no legitimate anonymous caller should reach these endpoints. In application or reverse-proxy access logs, the signal is a POST to the bridge's tool-invocation paths carrying no authentication material, particularly one invoking the terminal-execution tool. On the host, the process-lineage anchor is a shell or interpreter spawned by the bridge's own Node.js process — expected for a platform whose purpose is running agent tools, which is precisely why the discriminator has to be the request that caused it rather than the spawn itself. Egress from the container to destinations that are not the configured AI providers is the third surface, since a stolen key is only useful once it is used somewhere.

Triage: distinguishing benign from malicious here turns on authentication and origin, not on what the agent does afterwards. A real user's tool call arrives through the platform's own UI with a session behind it; the anomaly is an unauthenticated POST straight to the bridge paths, from a source outside the host or its expected client range. For the memory-poisoning half there is no network artifact at all after the fact — the only check is content-level review of the pattern store for entries no operator or agent run accounts for.

A single unauthenticated HTTP POST request to port 3001 gave full command execution inside the container. No token, no API key, no header check, no IP allowlist. Nothing.

The docker-compose.yml binds port 3001 to 0.0.0.0 by default, exposing the bridge on all network interfaces.

Noma Security 2026-07-29

Audit the AgentDB pattern store for injected agentdb_pattern-store entries; purge poisoned patterns. A patched redeploy alone does NOT undo poisoning.

Ruflo 2026-07-01

Defender actions

  • Upgrade Ruflo to 3.16.3 and confirm the MCP bridge is no longer bound to all interfaces — the shipped Docker Compose file exposed it by default, so a deployment that was never deliberately published to the network may still have been reachable.
  • For any Ruflo instance that was network-reachable before 3.16.3, rotate every AI-provider API key it held and audit the agent memory store for injected entries before returning it to service: the maintainer states a patched redeploy alone does not undo poisoning, so an upgrade leaves planted instructions in place and still steering the agent.

ATT&CK mapping

4 techniques mapped from the cited reporting · MITRE ATT&CK v19.1

Initial Access TA0001
T1190Exploit Public-Facing Application

Adversaries may attempt to exploit a weakness in an Internet-facing host or system to initially access a network. The weakness in the system can be a software bug, a temporary glitch, or a misconfiguration.

overlap matrix · ATT&CK page ↗

Execution TA0002
T1059.004Command and Scripting Interpreter: Unix Shell

Adversaries may abuse Unix shell commands and scripts for execution. Unix shells are the primary command prompt on Linux, macOS, and ESXi systems, though many variations of the Unix shell exist (e.g. sh, ash, bash, zsh, etc.) depending on the specific OS or distribution. Unix shells can control every aspect of a system, with certain commands requiring elevated privileges.

overlap matrix · ATT&CK page ↗

Credential Access TA0006
T1552.001Unsecured Credentials: Credentials In Files

Adversaries may search local file systems and remote file shares for files containing insecurely stored credentials. These can be files created by users to store their own credentials, shared credential stores for a group of individuals, configuration files containing passwords for a system or service, or source code/binary files containing embedded passwords.

overlap matrix · ATT&CK page ↗

Impact TA0040
T1565.001Data Manipulation: Stored Data Manipulation

Adversaries may insert, delete, or manipulate data at rest in order to influence external outcomes or hide activity, thus threatening the integrity of the data. By manipulating stored data, adversaries may attempt to affect a business process, organizational understanding, and decision making.

overlap matrix · ATT&CK page ↗

PROVENANCE

AI-generated · no human review · this permalink is the shareable record for the finding · verify operationally critical claims against the linked primary source.