Severity Daily

IT and AI security incidents, checked against the primary source

UI-TARS-desktop’s MCP servers listened on every interface with no authentication, and the fix is a commit, not a release

PATCH NOW — UI-TARS-desktop's MCP servers listened on every interface with no authentication, and the fix is a commit, not a release

Written by

in

CVE-2026-81735 scores 10.0 because the MCP command server had no authentication and listened on every interface — and the remediation is identified by a commit hash, not a version.

What happened

VulnCheck, acting as CNA, published CVE-2026-81735 on 27 August 2026, against ByteDance’s UI-TARS-desktop. GitHub’s advisory database carries it as GHSA-p68p-fq8j-3639, published and last updated the same day, where it is classified as an unreviewed advisory — a machine-imported record rather than one GitHub curated. The CVSS v4.0 base score is 10.0, vector AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H. The weakness is CWE-306, missing authentication for a critical function. Credit goes to Avishai Gonen of Pluto Security. Neither the CNA advisory nor the GitHub record states that exploitation is known.

The mechanism is described plainly in the advisory and is worth reading closely. In the project’s mcp-http-server package, startServer.ts defaulted its listen address to '::' when no host was configured, binding MCP transports to all interfaces. Authentication middleware was optional. The entry points for @agent-infra/mcp-server-commands and @agent-infra/mcp-server-filesystem initialized their servers without any middleware at all. And the commands server’s run_command tool, in VulnCheck’s wording, “hands its caller-supplied command string to promisify(child_process.exec).” GitHub’s record states the consequence directly: “any unauthenticated client able to reach the port could run arbitrary commands as the user running the server.” The filesystem server exposed file operations on the same terms.

The affected range, as VulnCheck states it, is >= 0, < commit c2ad42e3eb9b27830db41a3e6f51ca7179d9b168. That is the fix. There is no fixed version number in either record, and GitHub’s advisory lists affected and patched versions as unknown.

Why it matters

Start with '::'. That is the IPv6 unspecified address, and on a dual-stack host a socket bound there will in the common configuration accept IPv4 connections as well. A default of '::' is not a slightly permissive localhost — it is every interface the machine has, including the wireless one it is using at a conference, a hotel, or a client site. Developer tooling routinely assumes it is talking to itself over loopback, and that assumption is usually invisible until someone reads the default in the source.

This is now a recognizable shape in Model Context Protocol deployments, and it is structural rather than incidental. MCP was designed around a local, single-user model, with stdio as the original transport: the server is a subprocess of the client, on the same machine, run by the same person, and there is no network and therefore no authentication problem to solve. HTTP transport was added for good reasons and moves the same server onto a socket. What does not automatically move with it is the trust model. Code written under “the only caller is me” becomes code reachable by anyone who can route to the port, and nothing in the source has to change for that to happen — only a default.

Note what kind of flaw this is not. There is no parser bug here, no injection through a quoting mistake, no memory-safety issue. run_command passing a string to child_process.exec is the tool functioning exactly as designed; running commands is its entire purpose. CWE-306 is the correct classification precisely because the defect is the absence of a gate rather than the presence of a dangerous sink. That distinction matters for remediation: there is no input to validate and no filter to add. The only fixes are requiring authentication and not listening where you did not mean to listen. It also means any MCP server exposing a shell, a filesystem, or a browser is one bad default away from the same finding, whatever its code quality.

The bigger operational problem in this record is the remediation itself. “Affected: everything before commit c2ad42e” cannot be expressed as a version constraint. It does not fit an SBOM, a package manifest, a Dependabot rule, or a scanner signature. The @agent-infra packages are published and versioned, but the advisory does not say which published version first contains the fix, so a defender holding a lockfile cannot answer the only question that matters — am I affected — without reading the shipped code or diffing against the repository. Combine that with the GitHub record being unreviewed, which is the tier at which ecosystem alerting is least likely to fire, and you have a critical-severity finding that is unusually easy to miss through the normal channels. That is why we are filing this under Patch Now rather than Patch Soon: there is a fix, but there is no version to upgrade to, so the near-term control is configuration and network placement.

Finally, weigh the blast radius honestly. The advisory says arbitrary commands run “as the user running the server,” and the user running the server is a developer on a workstation. That machine typically holds cloud credentials, SSH keys, signed-in package registry tokens, source code for things that are not this project, and browser sessions. An agent desktop application is not a server in a rack with a scoped service account; it is the most credential-dense endpoint in most organizations. A 10.0 on a developer laptop is not a smaller problem than a 10.0 on a server, and in a lot of environments it is a larger one.

What to do

First, find out whether you are listening. On the machines where UI-TARS-desktop or the @agent-infra MCP servers are installed, enumerate listening sockets — ss -ltnp on Linux, lsof -iTCP -sTCP:LISTEN -P -n on macOS — and look for any node process bound to :: or 0.0.0.0 rather than 127.0.0.1 or ::1. That check is worth running against every MCP server you have deployed over HTTP, not only this one.

Where you find one, bind it explicitly. Set the host to loopback rather than relying on the default, and enable the authentication middleware rather than leaving it optional. Add a host firewall rule denying inbound connections to the port as a second layer, because a configuration file is easier to lose in an upgrade than a firewall rule.

For the fix itself, you need a build that contains commit c2ad42e3eb9b27830db41a3e6f51ca7179d9b168. Because no fixed version is published in either advisory, confirming that from a version number alone is not possible. Check the shipped code for the default listen address in startServer.ts, or build from a source tree that includes the commit, and treat any package version you cannot verify this way as unfixed.

If one of these servers was reachable from an untrusted network — a shared office, conference wifi, a coworking space, any laptop that left the building — do not treat this as a configuration cleanup. Rotate cloud credentials, registry tokens, and SSH keys present on that workstation, review shell history and scheduled tasks for entries you did not create, and check outbound connection logs if you have them. Unauthenticated command execution as the logged-in user leaves nothing meaningfully off limits.

Sourcing note

The CVE identifier, CVSS v4.0 score and vector, CWE assignment, affected range, fix commit, researcher credit, and technical description are taken from VulnCheck’s advisory for CVE-2026-81735, published 27 August 2026, with VulnCheck as the assigning CNA, and from GitHub’s advisory record GHSA-p68p-fq8j-3639, published and updated the same date. Both were read directly. Quoted phrases — including the run_command and child_process.exec description and the “any unauthenticated client able to reach the port” consequence — are the advisories’ own words.

The CVE record was published 27 August 2026; this story is published on the evening of 28 August. We could not reach NVD’s API for CVE-2026-81735 at press time — the service returned HTTP 429 rate-limit responses to repeated requests — so NVD’s own enrichment, including any NVD-assigned CVSS score that may differ from the CNA’s, has not been checked. Where a CNA score and an NVD score diverge we would normally show both.

Unresolved: neither advisory names a fixed release version, and we did not find one, so the affected published versions of @agent-infra/mcp-server-commands and @agent-infra/mcp-server-filesystem remain unenumerated. We have not fetched or reviewed the fix commit itself, have not tested any version of the software, and have seen no report of exploitation. No vendor statement from ByteDance was located.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *