// hackerlogs
login+ register
Supply ChainAgentic AIThreat BriefHigh

The Patch Landed 24 August. OpenCode's Advisory Waited a Month.

OpenCode 1.18.22 shipped on 24 August. GHSA-632h-h47v-g4x4 landed on 24 September with no CVE. Vulnerable builds were still being downloaded the week before.

The short answer

On 24 September 2026 Anomaly published GHSA-632h-h47v-g4x4 for OpenCode. A cross-site request to the local upgrade endpoint could make npm, pnpm, or Bun install an attacker-chosen package. The fix, release 1.18.22, shipped on 24 August. Anomaly did not request a CVE. Datadog says vulnerable versions were still a large share of downloads in the week before publication.

Key takeaways

  • Anomaly's GHSA-632h-h47v-g4x4 is the vendor primary. Datadog Security Labs is the researcher primary. Both are dated 24 September 2026.
  • The cross-site path is the local HTTP server. npm, pnpm, and Bun installs passed the upgrade target to the package manager as a package spec.
  • Release 1.18.22 shipped on 24 August. The advisory waited until 24 September because Anomaly asked for a month. There is no CVE.
  • Datadog counts more than 647,000 downloads of 82 vulnerable versions from 17 to 23 September, 38.9% of OpenCode downloads that week.
  • Curl, Homebrew, Chocolatey, and Scoop are outside this package-specifier path. A cached server password still rides on a top-level page load.

On 24 September Anomaly published GHSA-632h-h47v-g4x4. Datadog Security Labs published the research the same day. The fix had already shipped. OpenCode 1.18.22, which restricts the upgrade target to a semantic version and rejects the loose content type, was released on 24 August. Anomaly asked Datadog to wait a month. Anomaly did not request a CVE.

Hacker News on 25 September led with an Ollama-style model tool and a new reconstruction of the Hugging Face incident, which this archive already covers. US X trends were television, golf, and football. Google News over the last two days carried the Agentforce disclosure and the OpenAI review, not this GHSA.

High The advisory rates it High. The local server can ask npm, pnpm, or Bun to install a package the request names. High because that install runs as the user who started the server, not because a CVE number exists.

Three panels for the OpenCode upgrade advisory: a local server that accepted a package target, a fix that shipped on 24 August with no CVE, and downloads of old builds that continued into the week before publication.

What the advisory actually bounds.#

OpenCode is Anomaly's coding agent. opencode serve starts an HTTP server, on port 4096 in the examples both primaries use. Datadog shows opencode web starting that same server and printing a warning when OPENCODE_SERVER_PASSWORD is unset. The upgrade route accepts a target and, for an npm, pnpm, or Bun install, hands that string to the package manager as the thing to install. A semantic version was the intended input. A package spec can also be a remote archive. The route did not require a JSON content type, so a cross-site page load could submit a body the server still parsed. The advisory names that pair: origin was not checked, and the target was not limited to a version.

The advisory's affected range is 1.14.30 and later. The resolution names 1.18.22 as the patched release, in PR 44686, commit c6e76e9. That change requires an explicit target, requires it to be a semantic version, requires the supported JSON content type, and rejects a bodyless upgrade. A sentence in the advisory body says the author believes the impacted set stops at 1.18.16, because that is when a raw handler began accepting a body that is not JSON. Datadog's range is 1.14.30 through 1.18.21 inclusive. Use 1.18.22 as the floor. Do not shop the three sentences for the one that leaves you on an old build.

Curl, Homebrew, Chocolatey, and Scoop installs do not interpret the target as an alternate package. The advisory says the standalone CLI upgrade command is not itself the cross-site surface. Users who are not running the HTTP server are outside that path.

A password is not a full stop. The advisory says basic authentication blocks an unauthenticated request, and that a browser which has already signed in will attach those cached credentials to a top-level navigation. Datadog makes the same point. The warning the server prints when the password is unset is accurate. Setting the password does not retire the route.

The package clock and the impact clock.#

The package clock is the release. Datadog's timeline puts the vulnerable path in PR 24853 on 29 April, and the first vulnerable release, 1.14.30, on 30 April. Datadog found it on 11 August and reported it the same day through the GitHub advisory. Anomaly opened, merged, and released the fix on 24 August as 1.18.22, and the same day asked for a one-month publication delay. The public post and the public GHSA are both 24 September. That is 31 days of a fixed package with no public identifier.

The impact clock is who was still running the old server. Datadog's npm count for 17 through 23 September, three weeks after 1.18.22, is more than 647,000 downloads across 82 vulnerable versions. That was 38.9% of OpenCode downloads in the window. The count is not unique users, and it is not a count of people who had opencode serve or opencode web listening. It is evidence that "patched on 24 August" did not drain the old builds before the advisory existed.

This is the same split as the TanStack token and the MemTensor tag. The registry can grow a fixed version in a day. Laptops and CI images keep the version they resolved. Here the fixed version existed for a month before the identifier operators search for was published, and the identifier is a GHSA, not a CVE.

  1. PR 24853 introduces the vulnerable upgrade path. OpenCode 1.14.30 follows on 30 April, the first release Datadog calls vulnerable.
  2. Datadog reports GHSA-632h-h47v-g4x4. Anomaly releases 1.18.22 on 24 August and asks for a one-month publication delay.
  3. Through 23 September, Datadog counts more than 647,000 downloads of 82 still-vulnerable versions. 38.9% of OpenCode downloads that week.
  4. Datadog publishes. Anomaly publishes the GHSA the same day. No CVE is requested.

What this is not.#

It is not GHSA-vxw4-wv6m-9hhh, the January advisory for an unauthenticated server that could run commands, tracked as CVE-2026-22812. Different report, different code path, and that one did get a CVE. Mixing them will send a patch program at the wrong release.

It is not a claim that every OpenCode user was reachable. No server, no cross-site path. A curl or Homebrew install does not take the arbitrary-package branch the advisory describes. An npm install that never ran the server is a version to upgrade, not an account to declare burned.

It is not an in-the-wild campaign. Neither primary reports exploitation outside the lab. Do not invent victim counts from the 647,000 figure. That figure is downloads.

It is also not a bug you can hand to a CVE-only gate. The ticket name is the GHSA, the version floor 1.18.22, and the install method.

What to do.#

  1. Find every host running opencode serve or opencode web. Upgrade those installs to 1.18.22 or later. Check the binary on the host, not the version a different machine resolved last week.
  2. If the install method is npm, pnpm, or Bun and the version was below 1.18.22, and the server was listening while a browser on that host loaded pages you do not trust, rotate the tokens in that user account. The advisory's impact is code execution as that user. Include CI jobs that start the server for a test.
  3. Keep the server on localhost, and set a password anyway. Then assume a browser that has already authenticated will resend those credentials on a top-level navigation. The password is a speed bump in that case, which is what both primaries say. Do not publish port 4096.
  4. Record the install method next to the version. Curl, Homebrew, Chocolatey, and Scoop are outside the package-specifier path. They are not a reason to skip 1.18.22 if an npm install of the same tool also exists on the fleet.
  5. Alert on GitHub advisories for opencode-ai, not only on a CVE feed. This GHSA has no CVE. A gate that requires one will stay green while the server is still old.
  6. Treat an agent upgrade route as a supply-chain control. A local server that can install a global package from a string in a request is the same class of bug as a plugin installer that trusts a pin it never checks. The Plugin4Shell brief was the pin. This one is the upgrade target.

The front page did not need this for the fact to be operational. For 31 days the fixed release existed, the old builds were still what a large share of downloads resolved, and the public record had no CVE to search.

Frequently asked

Does an empty CVE field mean this is low severity?

No. The GitHub advisory rates the issue High. Anomaly's stated reason for skipping a CVE is that CVEs on GitHub Security Advisories invite a high volume of low-quality reports. That is a filing choice. A scanner that only keys on CVE identifiers will not see GHSA-632h-h47v-g4x4 at all.

Which OpenCode installs are actually exposed?

The advisory's cross-site path is the HTTP server from opencode serve, on an install managed by npm, pnpm, or Bun. Datadog adds opencode web, because that command starts the same server. Curl, Homebrew, Chocolatey, and Scoop do not treat the upgrade target as an alternate package. The CLI upgrade command, by itself, is not the cross-site surface. A password does not finish the job if the browser has already cached basic credentials.

Is 1.18.16 the last vulnerable release, or 1.18.21?

Do not pick the narrow sentence. The advisory's affected range is 1.14.30 and later, and the resolution names 1.18.22 as the patched release. A line in the advisory body says the author believes impact runs through 1.18.16. Datadog's tested range is 1.14.30 through 1.18.21 inclusive. Upgrade to 1.18.22 or later and then check the binary you are actually running.

Did Datadog report attacks in the wild?

No. Neither primary describes a customer incident. The impact statement is conditional: the server is running, the install is npm, pnpm, or Bun, the browser can reach it, and someone opens an attacker-controlled page. The download count is registry traffic, not a count of compromised machines.

Sources

Related