The project’s own advisory scores the same flaw 10.0 and titles it a sandbox escape; the CVE record published today scores it 9.3 on CVSS v4.0 with every subsequent-system metric set to none.
What happened
VulnCheck published CVE-2026-88899 to the National Vulnerability Database at 4:18 p.m. UTC on September 10, 2026, revising it at 7:58 p.m. UTC. The description reads: “knowns versions before 0.31.0 fail to properly validate the x-opencode-directory request header in the /api/opencode proxy endpoint. Remote attackers can supply arbitrary directory paths to execute file operations outside the project root on the host system.”
Knowns is an open-source AI project-management and coding agent, distributed on npm as knowns and developed as knowns-dev/knowns. NVD’s primary score is 9.8 Critical on CVSS v3.1, vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H, with a secondary v4.0 score of 9.3. The weakness is CWE-73, external control of file name or path. The affected range is everything below 0.31.0; 0.31.0 is named as the fix. As with the batch three days ago, the assigning CNA is VulnCheck at [email protected], and vulnStatus reads Deferred.
The version that was the answer on Sunday is the question today
On September 7, 2026, VulnCheck pushed six Knowns CVEs into NVD inside one hour. Severity Daily covered that batch: five of the six named 0.30.0 as the unaffected version, and the sixth described a server-side request forgery reaching 0.33.0, the current release. The operational instruction a reader could draw from those five records was to get to 0.30.0.
Today’s record makes 0.30.0 the last affected version. The npm registry gives the release times: 0.30.0 published August 16, 2026 at 10:56 a.m. UTC; 0.31.0 published August 23, 2026 at 4:36 p.m. UTC, a week later. Someone who read the September 7 records and moved to 0.30.0 landed on a build that carries a 9.8 unauthenticated path-control flaw. Nothing in those five records said so, because the flaw that today’s record describes had no CVE on September 7.
That is not an error in the September 7 batch, and it is not an error in our reporting of it — those records said what they said. It is a structural property of reading fix guidance out of a CVE feed one batch at a time. A “fixed in” version is only a statement about the flaw in front of you.
Two scores, one boundary
The project published its own GitHub Security Advisory for this flaw, GHSA-9h2q-r9fh-f98w, on September 9, 2026 — a day before the CVE. Its title is “Sandbox Escape: Unauthenticated Header Injection Grants AI Agent Unrestricted Access to Host Filesystem.” It rates the flaw Critical, CVSS 10.0, vector CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H. It credits uziii2208, one of the two reporters named on the MCP path-traversal advisory in Sunday’s batch. Its CVE field reads “No known CVE.”
Set the two v4.0 vectors side by side. They are identical through the exploitability metrics and identical on vulnerable-system impact — VC:H/VI:H/VA:H in both. They diverge on exactly three characters’ worth of judgment. The project writes SC:H/SI:H/SA:H: high confidentiality, integrity and availability impact on a subsequent system. VulnCheck writes SC:N/SI:N/SA:N: none. That single triplet is the whole gap between 10.0 and 9.3.
The subsequent-system metrics in CVSS v4.0 exist to answer one question: did the impact cross a security boundary out of the vulnerable component into something else? The project’s answer is yes, and its advisory title names the boundary — a sandbox, and the host filesystem on the other side of it. VulnCheck’s vector says no impact crossed. Yet VulnCheck’s own description, in the same record, ends with the words “outside the project root on the host system.”
We are not picking one. Both scores are on the public record, both come from parties with a claim to know, and the disagreement is worth more to a reader than either number alone: it is a disagreement about whether the project root is a security boundary or merely a working directory.
The mechanism
The advisory quotes the vulnerable condition in proxyOpenCode(): if activeRoot != "" && r2.Header.Get("x-opencode-directory") == "". The server injects the legitimate project root only when the client’s header is empty. Send a non-empty x-opencode-directory and the value passes through untouched to the embedded OpenCode agent daemon, which then operates on whatever path the request named. The ?directory query parameter behaves the same way.
The fix, in the project’s own words: “Unconditionally overwrite x-opencode-directory and ?directory with activeRoot in proxyOpenCode(). Both values must be treated as server-controlled, not client-supplied.” The patched code deletes the header, then sets it, regardless of what arrived.
Why it matters
The bug is a fail-open guard, and it fails open in the direction that is easiest to miss in review. The condition reads as a sensible default-setter: if we have a root and the caller did not specify one, fill it in. Read as a security control it says the opposite — a caller who does specify one is trusted. Defaulting logic and enforcement logic look nearly identical in source, and the difference between them is whether the client’s value is allowed to survive.
What makes this worth attention beyond the code is what sits on the other end of the proxy. This is not a file-read primitive returning bytes to the attacker. It is a re-pointing of an autonomous agent’s working directory. The agent still does what it was built to do — read files, write files, run tools — and it does so with the privileges of the process a developer started on their own machine or on a shared build host. Path validation that only inspects the paths in a request misses this entirely, because the malicious value is not a traversal string. It is a legitimate absolute path handed to a component that was never supposed to receive one from outside.
The score disagreement matters practically, not just as a record curiosity. Downstream consumers pick a number and act on it. A 10.0 with subsequent-system impact reads, to most triage processes, as “this leaves the container.” A 9.3 with those metrics zeroed reads as “serious, but contained.” An operator running this agent on a build machine with repository credentials in the environment is entitled to know that the two published scores answer that question differently. And the third artifact — the GHSA still saying “No known CVE” while the CVE that cites it has existed since this afternoon — is the same record lag this publication has now seen on Renovate, on AVideo, and on Sunday’s Knowns batch.
What to do
Upgrade to 0.33.0, not to 0.31.0. 0.31.0 closes this flaw specifically, but the current release is 0.33.0, published September 5, 2026 at 4:57 p.m. UTC, and the release cadence here is roughly weekly. Anyone who moved to 0.30.0 on the strength of Sunday’s records should treat that as an interim stop, not a destination.
Note what 0.33.0 does not fix. CVE-2026-86539, the server-side request forgery in POST /api/embedding-models/test from Sunday’s batch, has an affected range running through 0.33.0 with no fixed version named. Upgrading does not clear it.
Do not expose the agent’s HTTP surface. The endpoint at issue is unauthenticated and reachable over the network in the vector both parties agree on. If this process listens anywhere other than loopback, that is the control worth changing today regardless of version.
Check what the process can reach. Whatever directory the agent can be re-pointed at, it can act on with the privileges it already has. On a developer laptop that is a home directory; on a shared runner it is likely credentials.
Sourcing note
Checked directly: the NVD record for CVE-2026-88899 (published September 10, 2026 at 4:18 p.m. UTC, last modified 7:58 p.m. UTC, vulnStatus Deferred, CNA VulnCheck) for the description, both vectors, CWE-73 and the affected range; GHSA-9h2q-r9fh-f98w, published by the project on September 9, 2026, for the title, the 10.0 v4.0 vector, the vulnerable condition, the fix wording, the credit to uziii2208 and the “No known CVE” field; and the npm registry, reachable directly from this container, for the release timestamps of 0.30.0, 0.31.0, 0.32.0 and 0.33.0.
Could not reach: api.github.com, so the fix commit was not read line by line and the quoted condition is the advisory’s rendering of it rather than our own read of the diff. Download figures for the npm package are also unavailable from here, so the deployed scale of Knowns is unknown to us and no estimate is offered.
Unresolved: which of the two v4.0 scores the parties would defend if asked, and whether the project intends to update GHSA-9h2q-r9fh-f98w to carry the CVE ID. No exploitation of this flaw has been reported and none is claimed here.
