OpenCode had two unrelated security problems in one week. An intrusion into a legacy system may have exposed OpenAI, Anthropic and Google API keys saved in OpenCode Console, and a quiet 28 September fix closed a Windows and WSL command injection in MCP OAuth sign in. Rotate Console keys and upgrade to 1.18.33.
The two issues involve different parts of the product and different fixes. They share one lesson for anyone running AI coding tools across a team: these tools hold real credentials, talk to remote servers you may not control, and change faster than most inventories track. Below are exact versions, commits, paths and commands, plus what is still unknown.
| Console provider key breach | MCP OAuth sign in command injection | |
|---|---|---|
| What it is | Unauthorized access to a legacy OpenCode system that held provider keys saved in Console | A remote MCP server can make OpenCode run commands on Windows or WSL during OAuth sign in |
| Who is affected | About 1.4% of Console users, all with an external provider linked, according to OpenCode | Users of opencode-ai 1.0.137 through 1.18.32 on Windows or WSL who sign in to a remote MCP server |
| Fixed by | Revoking the key at OpenAI, Anthropic or Google | Upgrading to 1.18.33 (28 September 2026) |
| CVE | None (service incident) | None requested or issued |
| Your first command | Check your inbox for "Action Required: Potential provider key breach" | opencode --version |
What happened
The Console provider key breach
OpenCode Console is the optional hosted side of OpenCode. According to OpenCode's documentation, it is a gateway to a set of models the OpenCode team has tested. You sign in, add credits, copy an API key and paste it into the OpenCode terminal app with /connect. Workspace owners and admins can invite members, choose which models are enabled, set monthly budgets for the workspace and each member, and connect their own provider accounts. That last feature is the one that matters here. When a workspace links its own OpenAI, Anthropic or Google key, Console holds that key and uses it on behalf of team members, so members can use the models without ever seeing the key, as The Hacker News describes it.
On the night of 16 October 2026, an intruder reached what OpenCode called a legacy system. The notification email, which users posted publicly on Reddit and Discord according to Infosecurity Magazine, says OpenCode "identified unauthorized access to a legacy system" that it was in the process of decommissioning. BleepingComputer reports that the email gives 00:30 UTC on 17 October as the earliest point at which affected keys could have been exposed.
OpenCode emailed affected users on the morning of 17 October with the subject line "Action Required: Potential provider key breach" and posted about the incident on X the same day. OpenCode said the incident was "related to a large-scale distillation attack" that affected 1.4% of Console users, all of whom had an external provider linked. Users who did not receive the email were not affected, according to the company.
Co-founder Dax Raad drew a clear line between the hosted service and the open source tool. TechCrunch quotes him: "Note this is the OpenCode Console, not OpenCode itself, those keys never come to us." The OpenCode terminal and desktop apps keep provider keys locally in a SQLite database, The Hacker News reports, and OpenCode's CLI documentation lists ~/.local/share/opencode/auth.json as the local credential store for opencode auth login.
Raad also said that attackers had been trying to break in for about 48 hours, and that the team ran defensive AI agents around the clock during that period, according to The Hacker News and TechCrunch. TechCrunch reports that refunds for unauthorized charges were underway and that OpenCode made one hosted model free for users the same night.
Users reported real money lost. The Hacker News, citing Dealroom, Notebookcheck and posts by affected users, lists reports of $281 on OpenAI and $168 on Anthropic for one user, about $1,700 for another, $400 of unauthorized Anthropic usage reported on Reddit, and about €200 of Google usage followed by a suspended project for a fourth. None of these figures have been independently verified. BleepingComputer adds that some users reported suspended Google Cloud projects after Google detected what users quoted as "abusive activity consistent with hijacked resources." That wording comes from user reports, not from a Google statement.
On the provider side, TechCrunch reports that Anthropic and Google blocked API keys they believed were exposed, and that OpenAI worked with OpenCode to restore access and refund API customers for credits used in the attack. We could not find a primary statement from any of the three providers confirming this, so treat it as reported, not confirmed.
The MCP OAuth sign in command injection
The second issue is a vulnerability in the OpenCode client itself. It was found by an AI security research team, reported privately on 29 August 2026 and written up publicly with a page dated 19 October 2026. The Hacker News covered it on 22 October.
OpenCode can connect to remote MCP (Model Context Protocol) servers. Many remote MCP servers require OAuth sign in. When OpenCode needs to sign in, it asks the server where its authorization page is and then opens that address in your browser. On Windows and WSL, the address went through a PowerShell command line built by the npm open package at version 10.1.2. That package escaped the program name but not the target. PowerShell expands a particular kind of embedded expression inside double quoted strings, so a malicious server could return an ordinary looking https address that also contained a command. PowerShell would run the command, the browser launch would then fail, and OpenCode would discard the failure.
The researchers proposed a CVSS 3.1 score of 9.8. The fix shipped in OpenCode 1.18.33 on 28 September 2026 as part of a pull request titled as a refactor. No CVE was requested and no security advisory was published. According to the researchers, Anomaly, the company behind OpenCode, said a malicious MCP server is outside its threat model. OpenCode's own security policy lists "MCP server behavior" as out of scope, with the rationale that external MCP servers you configure are outside its trust boundary.
Because there is no CVE and no GitHub security advisory, software composition analysis tools and dependency bots that match against vulnerability databases will not flag vulnerable OpenCode versions. You have to find them yourself.
Timeline
Times are given where a source publishes them. Where a page shows a time without a year or time zone, we say so.
| Date and time | Event | Source |
|---|---|---|
| 18 Oct 2023 | Issue #323, "OS command injection on windows when opening urls", is opened against the open package | sindresorhus/open issue #323 |
| 9 Jul 2025 | Advisory GHSA-6xpm-ggf7-wc3p (CVE-2025-6514) published for the same bug class in mcp-remote, fixed in 0.1.16 | GitHub advisory database |
| 12 Nov 2025 | open issue #323 closed as "not planned" | sindresorhus/open issue #323 |
| 15 Nov 2025 | open v11.0.0 released, including "Fix PowerShell argument escaping" | open releases page; research write up gives the year |
| 7 Dec 2025 | OpenCode commit 509e43d6 adds a call that opens the OAuth authorization URL with open | Research write up |
| 9 Dec, 03:01 (page time, year and zone not shown) | OpenCode v1.0.137 released: "Added OAuth authentication support for remote MCP servers" (PR #5014) | OpenCode GitHub release v1.0.137 |
| 29 Aug 2026 | MCP flaw reported privately through a GitHub security advisory | Research write up |
| 14 Sep (page shows no year; after v11.0.0) | open v11.0.4 released | open releases page |
| 24 Sep 2026 | OpenCode publishes GHSA-632h-h47v-g4x4, an unrelated High severity advisory, showing advisories are used for other issues | OpenCode security page |
| 25 Sep 2026 | Researchers follow up; Anomaly says malicious MCP servers are outside its threat model; researchers ask for a CVE | Research write up |
| 25 Sep 2026, branch deleted 23:09 (page time) | PR #51414 "refactor(core): share a browser opener across opencode and tui" merged into dev as commit 29f07e0c | OpenCode PR #51414; research write up |
| 28 Sep, 04:22 (page time) | OpenCode v1.18.33 released, commit 51ef4be; notes mention MCP browser launch failure reporting, not security | OpenCode GitHub release v1.18.33 |
| 4 Oct 2026 | Research report publication date as given in the write up's own timeline | Research write up |
| 16 Oct 2026, night | Intruder reaches a legacy OpenCode system | OpenCode email via Infosecurity Magazine; The Hacker News |
| 17 Oct 2026, 00:30 UTC | Earliest possible exposure of affected keys, per OpenCode's email | BleepingComputer |
| 17 Oct 2026, morning | Emails titled "Action Required: Potential provider key breach" go out; OpenCode posts on X | The Hacker News; TechCrunch |
| 18 Oct 2026 | Raad says attackers had been trying to get in for about 48 hours | The Hacker News |
| 19 Oct 2026, 12:28 PDT | TechCrunch publishes, reporting provider key blocks and refunds | TechCrunch |
| 19 Oct 2026, 13:27 (page time) | BleepingComputer publishes, citing the 00:30 UTC exposure window | BleepingComputer |
| 19 Oct 2026 | MCP research write up page dated 19 Oct; The Hacker News and Infosecurity Magazine cover the Console breach | Research write up; The Hacker News; Infosecurity Magazine |
| 22 Oct 2026 | The Hacker News covers the MCP flaw | The Hacker News |
Who is affected
| Group | Console breach | MCP flaw | What to do |
|---|---|---|---|
| Console workspace with an external OpenAI, Anthropic or Google key linked, and you got the email | Yes, according to OpenCode | Depends on your OpenCode version and platform | Rotate every linked provider key now and review usage from 16 October |
| Console workspace with a linked key, no email | OpenCode says not affected | Depends | Rotate anyway if you want certainty; it costs little |
| Console user with only OpenCode pay as you go credits, no linked provider | Not in the affected group as described | Depends | No key rotation needed for this incident |
OpenCode CLI or desktop user with keys in local auth.json | Not affected, per OpenCode | Yes if on Windows or WSL and running 1.0.137 through 1.18.32 | Upgrade; check MCP servers |
| OpenCode on macOS or Linux (not WSL) | Not affected by the client bug | Not affected, per the researchers | Upgrade anyway for other fixes |
Teams building their own MCP client that calls open on server supplied URLs | Not related | Same bug class may apply | Check your open version and URL handling |
Affected and fixed versions
| Component | Affected | Fixed | Platform | Source |
|---|---|---|---|---|
opencode-ai (npm) | 1.0.137 through 1.18.32 | 1.18.33, released 28 September 2026 | Windows and WSL only | Research write up; The Hacker News |
open (npm), as used by OpenCode | 10.1.2 (pinned by OpenCode) | OpenCode moved to 11.0.4 | Windows and WSL code path | OpenCode PR #51414 |
open (npm), upstream | Releases before 11.0.0 lack the escaping fix | 11.0.0 "Fix PowerShell argument escaping"; the researchers credit 11.0.4's single quoting as the real fix | Windows | open releases; research write up |
mcp-remote (npm), related bug class | 0.0.5 through 0.1.15 | 0.1.16 | Full command execution on Windows; limited on macOS and Linux | GHSA-6xpm-ggf7-wc3p |
| OpenCode Console | Legacy system breached 16 to 17 October | Service side; your fix is key revocation at each provider | Hosted | OpenCode email via press |
Technical details
Every value in this section comes from the sources listed at the end. Where sources disagree, we say so.
Console breach: what the notice and reporting say
| Field | Value | Source |
|---|---|---|
| Service | OpenCode Console, the optional hosted gateway and workspace service | OpenCode docs |
| System reached | "a legacy system that we were in the process of decommissioning" | OpenCode email quoted by Infosecurity Magazine |
| Date of intrusion | Night of 16 October 2026 | The Hacker News; Infosecurity Magazine |
| Earliest possible key exposure | 17 October 2026, 00:30 UTC | OpenCode email per BleepingComputer |
| Data at risk | Third party provider keys saved in Console workspaces: OpenAI, Anthropic, Google | The Hacker News |
| Share of users | 1.4% of Console users, all with an external provider linked | OpenCode statement, multiple outlets |
| Notification subject | "Action Required: Potential provider key breach" | The Hacker News |
| Status language | Keys "may have been exposed"; incident described as ongoing on 17 October | The Hacker News |
| Attack framing | "related to a large-scale distillation attack" | OpenCode statement |
| Duration of attempts | About 48 hours, per Raad | The Hacker News; TechCrunch |
| Not affected | OpenCode CLI and desktop apps, which store keys locally in SQLite | Raad, via The Hacker News and TechCrunch |
| Published indicators of compromise | None | No source lists IP addresses, domains or user agents |
Two conflicting statements sit inside the same notice. BleepingComputer reports that the email says no data appears to have been exposed, while the same notice and OpenCode's public statements say keys may have been exposed. Read this as: OpenCode has not confirmed that keys were copied, but it is treating them as exposed. You should too.
MCP flaw: identifiers and scores
| Field | Value | Source |
|---|---|---|
| Package | opencode-ai on npm, published by Anomaly (anomalyco) | Research write up |
| CVE | None requested or issued | Research write up; The Hacker News |
| GHSA | None for OpenCode. GHSA-6xpm-ggf7-wc3p cited in the write up belongs to mcp-remote CVE-2025-6514 | Research write up; GitHub advisory database |
| Weakness | CWE-78 (OS command injection), secondary CWE-88 (argument injection) | Research write up |
| Proposed CVSS 3.1 | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H, 9.8 Critical | Research write up |
| Related CVE | CVE-2025-6514, mcp-remote, CVSS 3.1 9.6, AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H | GitHub advisory database |
| Exploitation | No signs of exploitation reported; no indicators published | The Hacker News |
| Vendor position | Malicious MCP servers are outside the threat model; "MCP server behavior" out of scope in SECURITY.md | Research write up; OpenCode security policy |
A note on the score. The proposed vector sets user interaction to none. The Hacker News says exploitation requires the developer to start sign in, for example by running opencode mcp auth, and that merely configuring a server or opening a session does not trigger it. OpenCode's MCP documentation adds that OpenCode starts the OAuth flow automatically when a server answers with HTTP 401 and prompts you on first use. If a scorer counts that prompt as user interaction, the same vector with UI:R works out to 8.8 under the CVSS 3.1 formula, by our calculation. The related mcp-remote CVE was scored with UI:R. Either way it is high severity on the affected platforms.
Code path and fix
The researchers trace the vulnerable 1.18.32 code path as follows: the MCP server's OAuth discovery document is parsed by the MCP SDK, the authorization_endpoint value flows through oauth-provider.ts and mcp/index.ts to browser.ts, which calls open(), which on Windows runs PowerShell. There was no URL scheme check and no comparison against the configured server's origin.
On Windows, open 10.1.2 builds a command line, encodes it as base64 UTF-16LE and passes it to powershell -EncodedCommand. The application name is escaped and the target is not. The researchers say open 11.0.4 wraps the target in single quotes, which PowerShell does not expand, and call that the true fix.
PR #51414, by rekram1-node, made three changes, according to the PR and the write up:
- It bumped
openfrom 10.1.2 to 11.0.4, moved the dependency into@opencode-ai/core, and added a rootoverridesentry so transitive copies pulled in bystorybookand@hey-api/openapi-tsresolve to the same version. - It added
openUrl(input)in a new@opencode-ai/core/openmodule. The function parses the target, launches onlyhttp:andhttps:URLs and passes the normalizedhreftoopen. Tests inpackages/core/test/open.test.tscover unparseable strings,file:,javascript:, custom schemes and UNC paths. - It added the same http and https check inside the MCP OAuth provider's
redirectToAuthorizationmethod, with tests inpackages/opencode/test/mcp/oauth-provider.test.ts.
The PR consolidated eight call sites that previously imported open directly: cli/cmd/account.ts, cli/cmd/web.ts, plugin/digitalocean.ts, plugin/snowflake-cortex.ts and mcp/browser.ts in opencode, and ui/link.tsx, component/dialog-retry-action.tsx and app.tsx in tui. The researchers stress that the scheme check alone would not have stopped the attack, because the malicious value is a well formed https URL. The version bump is what closed it.
The v1.18.33 release notes, published by the opencode-agent account at commit 51ef4be, say "MCP browser launch failures are now reported when the launcher exits immediately" and that debug configuration output now hides credentials and sensitive headers. Neither line describes a security fix.
Files, paths and commands on disk
| Item | Value | Source |
|---|---|---|
| Local provider credentials | ~/.local/share/opencode/auth.json | OpenCode CLI docs |
| Stored MCP OAuth tokens | ~/.local/share/opencode/mcp-auth.json | OpenCode MCP docs |
| Config files | opencode.json or opencode.jsonc, servers under the mcp key | OpenCode MCP docs |
| Remote server entry | "type": "remote", url, optional headers, enabled, timeout (default 5000 ms), oauth | OpenCode MCP docs |
| Disable automatic OAuth | "oauth": false | OpenCode MCP docs |
| Inventory commands | opencode --version, opencode mcp list, opencode mcp auth list, opencode mcp debug <name>, opencode mcp logout <name> | OpenCode CLI and MCP docs |
| Upgrade command | opencode upgrade, or opencode upgrade <version> with --method for curl, npm, pnpm, bun or brew | OpenCode CLI docs |
Indicators of compromise
None have been published for either issue. OpenCode has not released IP addresses, user agents or request patterns for the Console intrusion, and the researchers reported no exploitation of the MCP flaw. If you see a list of "OpenCode IOCs" circulating, check where it came from before acting on it.
How it works
Why a stored provider key is so valuable
A provider API key is a bearer credential. Whoever presents it gets billed access to the provider's models, with no further proof of identity unless you have added restrictions. When you link a key to a hosted gateway, you are trusting that service to keep the key safe and to use it only for your team's requests.
Two details from The Hacker News coverage matter for your response. First, deleting a key from Console does not revoke it. The key stays valid at OpenAI, Anthropic or Google until you revoke it there. Second, a Console budget only limits spend that flows through Console's gateway. Someone who copied the key and calls the provider directly is not subject to that budget at all. The only limits that apply to them are the ones you set at the provider.
"Distillation" is the term model providers use for harvesting large volumes of a model's answers to train another model. Stolen keys are useful for that because the thief's usage is billed to someone else. OpenCode has not explained how the intrusion connects to distillation, and TechCrunch notes that some observers questioned whether the breach had anything to do with distillation at all.
Why the MCP flaw needs only a server you once trusted
Remote MCP servers that require OAuth follow a discovery chain defined in the MCP authorization specification. The client calls the server, gets HTTP 401 with a WWW-Authenticate header, fetches the server's protected resource metadata, learns which authorization server to use, fetches that authorization server's metadata and reads its authorization_endpoint. Then it opens a browser at that address with the PKCE challenge and a resource parameter. Every value in that chain comes from the remote side.
The MCP specification lets the authorization server be a separate entity from the MCP server, so the authorization address can legitimately live on another host. That is fine for OAuth. It becomes dangerous when the client hands that remote supplied string to something that interprets it, such as a shell.
The researchers point out that the server does not need to be malicious on the day you add it. A server that is later compromised, a hijacked registry entry, a lookalike name, or a domain that expires and changes hands can all serve the same malicious discovery document. No prompt injection is needed and nothing needs to be installed.
Why only Windows and WSL
On macOS and Linux, open launches the browser through open or xdg-open without a shell, so the URL arrives as a single argument and is not interpreted. On Windows, and in WSL where the Windows browser is launched, open 10.1.2 went through PowerShell with the target inside a double quoted string. That is the whole difference. The same split shows up in the earlier mcp-remote research, where Windows allowed full command execution and macOS and Linux allowed only limited execution.
Why a scheme check was not enough
Checking that the URL starts with https: stops file:, javascript: and custom scheme tricks. It does nothing about characters inside an https URL that a shell treats as code. The safe fixes are to never pass URLs through a shell, or to quote them in a way the shell cannot expand, and to treat every field from a remote server as untrusted input.
What changed since first reports
- Scope of the Console breach. Early posts on 17 October described a breach of OpenCode generally. By 19 October, OpenCode and the press were consistent that only Console, and only workspaces with linked external providers, were involved.
- Provider actions. TechCrunch's 19 October report added that Anthropic and Google blocked keys they believed were exposed and that OpenAI was refunding credits. BleepingComputer's report the same day contains no provider statements. We found no provider primary statement.
- Exposure window. BleepingComputer's reading of the email gave a precise start, 00:30 UTC on 17 October. Earlier reports said only "last night."
- MCP flaw dates. The research page carries a 19 October date, while its own timeline lists 4 October as the publication date. The Hacker News treats 19 October as the disclosure date.
- User interaction. The research write up says no interaction is needed beyond connecting during OAuth. The Hacker News says the developer must start sign in. OpenCode's docs say the flow starts automatically on a 401 and prompts on first use. These are compatible readings of one behaviour, but they lead to different CVSS scores.
What to do now
Work through Part A if you used Console with your own provider keys. Work through Part B if anyone on your team runs OpenCode on Windows or WSL. Part C covers looking for signs of misuse, and Part D is for teams building their own MCP clients.
Part A: rotate provider keys stored in Console
-
Find every key that was ever stored. Search your mail for "Action Required: Potential provider key breach". Then list every OpenAI, Anthropic and Google key that was linked to any Console workspace, including keys another admin added. Rotate even if you did not get the email if you cannot rule out exposure.
-
Create replacements first, scoped and capped. For each provider, create a new key dedicated to one tool, with the narrowest scope and a spend cap, before revoking the old one. The details per provider are below.
-
Revoke the old key at the provider. Removing it from Console is not enough.
-
Update every consumer. CI secrets,
.envfiles, local agent configs, production services and teammates' machines. A quick way to find local copies on a developer machine:# Names only; do not print values into shared logs grep -rIl --exclude-dir=node_modules -e OPENAI_API_KEY -e ANTHROPIC_API_KEY \ -e GEMINI_API_KEY -e GOOGLE_API_KEY ~/ 2>/dev/null | head -50 -
Confirm the old key is dead. Make one request with the old key and confirm the provider rejects it with an authentication error, or check its status in the provider's key list.
-
Review usage back to at least 16 October. Look for spikes, models you do not use and traffic at odd hours. Keep screenshots or exports for any refund request.
Anthropic
Anthropic's Admin API can list, deactivate and report on keys. It requires an Admin API key (these start with sk-ant-admin), an OAuth token with the org:admin scope, or a personal or service account key not scoped to a workspace. The Admin API is not available for individual accounts; those users can use the Usage and Cost pages in the Claude Console instead.
# List active API keys in the organization
curl "https://api.anthropic.com/v1/organizations/api_keys?limit=100&status=active" \
-H "x-api-key: $ANTHROPIC_ADMIN_KEY" \
-H "anthropic-version: 2023-06-01"
# Deactivate a key that was linked to Console
curl "https://api.anthropic.com/v1/organizations/api_keys/apikey_REPLACE_ME" \
-H "x-api-key: $ANTHROPIC_ADMIN_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{"status": "inactive"}'
# Hourly usage for that key since 16 October, grouped by model
curl "https://api.anthropic.com/v1/organizations/usage_report/messages?\
starting_at=2026-10-16T00:00:00Z&\
ending_at=2026-10-22T00:00:00Z&\
api_key_ids[]=apikey_REPLACE_ME&\
group_by[]=model&\
bucket_width=1h&\
limit=144" \
-H "anthropic-version: 2023-06-01" \
-H "x-api-key: $ANTHROPIC_ADMIN_KEY"
# Daily cost by workspace and description for the same window
curl "https://api.anthropic.com/v1/organizations/cost_report?\
starting_at=2026-10-16T00:00:00Z&\
ending_at=2026-10-22T00:00:00Z&\
group_by[]=workspace_id&\
group_by[]=description" \
-H "anthropic-version: 2023-06-01" \
-H "x-api-key: $ANTHROPIC_ADMIN_KEY"
Anthropic's documentation says hourly buckets default to 24 per request with a maximum of 168, so a six day window at 1h needs limit=144 or paging with has_more and next_page. Usage typically appears within five minutes of a request. Keys in the list response include expires_at, so you can give the replacement key an expiry and audit it later. Put the new key in its own workspace if you want its spend and usage separated.
OpenAI
OpenAI's production best practices guide recommends project API keys with an expiration date set at creation, separate projects for staging and production, and a rotation process in which you create the replacement, update applications, and revoke the old key only after the new one works. Admins can cap key lifetime in Platform settings, and API Key Governance can restrict new keys to service accounts. Usage per key is visible on the Usage page once tracking is enabled; keys generated before 20 December 2023 do not have tracking on by default and show earlier usage as "Untracked."
For spend, OpenAI's spend limits guide distinguishes spend alerts, which only notify, from a hard spend limit, which blocks requests once tracked spend reaches the amount. Set it per project under Project settings, Limits, Spend, Edit spend limit, then turn on "Enforce a hard limit." Requests over the limit fail with HTTP 429 and project_spend_limit_exceeded. The guide notes enforcement is not instantaneous, so spend can slightly exceed the limit. Give the key used by your coding tool its own project with a hard limit.
Google (Gemini API)
Google's Gemini API documentation says each key belongs to a Google Cloud project, recommends treating the key like a password, and describes a leak response: create a replacement, deploy it, disable the old key once the new one is confirmed, then audit billing and usage. All new keys created in Google AI Studio from 28 May 2026 are auth keys bound to a service account, and the API rejects unrestricted standard keys.
# List keys in the current project, including recently deleted ones
gcloud services api-keys list --show-deleted
# If you only have the key string from a config file, find its key ID and project
gcloud services api-keys lookup KEY_STRING
# Restrict the replacement key to the Gemini API only
gcloud services api-keys update KEY_ID \
--api-target=service=generativelanguage.googleapis.com
# Delete the old key once the replacement works (check gcloud services api-keys --help)
gcloud services api-keys delete OLD_KEY_ID
Google Cloud's documentation notes that a deleted key can be restored with gcloud services api-keys undelete within 30 days, and recommends setting both API restrictions and application restrictions, such as allowed IP addresses, on every key. Set a billing budget alert on the project so the next abuse shows up as an alert rather than a suspension.
Part B: OpenCode on Windows and WSL
-
Find every install. On each Windows machine, in PowerShell:
opencode --version where.exe opencode npm ls -g opencode-ai wsl.exe -l -vThen inside each WSL distribution:
command -v opencode && opencode --version npm ls -g opencode-ai 2>/dev/nullAnything from 1.0.137 through 1.18.32 is affected on these platforms.
-
Upgrade. Run
opencode upgrade, or pin a version withopencode upgrade v1.18.33(or a later version) and the--methodflag that matches how it was installed. For npm installs,npm install -g opencode-ai@latestalso works. Runopencode --versionagain to confirm. -
List remote MCP servers and their auth state.
opencode mcp list opencode mcp auth listFor each remote server, ask: who runs it, is the domain still theirs, and do we still need it? Remove anything you cannot vouch for from
opencode.jsonoropencode.jsonc, in both the project and your global config. -
Clear tokens for servers you remove. Run
opencode mcp logout <name>. Stored MCP OAuth tokens live in~/.local/share/opencode/mcp-auth.json. -
Turn off automatic OAuth where you do not need it. If a server uses API key headers, set
"oauth": falseon its entry so a 401 cannot start a browser flow. -
If you cannot upgrade a machine yet, the researchers' advice is to remove unvetted remote MCP servers from its configuration or formally accept the risk, and not to run
opencode mcp authagainst any server you do not control.
Part C: look for signs of misuse
For the Console breach, your evidence is at the providers: the usage and cost views above. Look for requests from models you never use, volume at hours your team is offline, and any traffic after you deactivated a key, which would point to a second copy you missed.
For the MCP flaw on Windows, the vulnerable launch path ran powershell -EncodedCommand. Legitimate browser launches on vulnerable versions also used that path, so the useful check is to decode the command and see whether it contains anything other than opening the authorization page.
# Sysmon process creation events mentioning opencode and an encoded PowerShell command
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Sysmon/Operational'; Id=1} -MaxEvents 20000 |
Where-Object { $_.Message -match 'EncodedCommand' -and $_.Message -match 'opencode' } |
Select-Object TimeCreated, Message
# Without Sysmon: Security log 4688, if command line auditing is enabled
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4688} -MaxEvents 20000 |
Where-Object { $_.Message -match 'EncodedCommand' } |
Select-Object TimeCreated, Message
# Decode a captured value to read what PowerShell was asked to run
$b64 = 'PASTE_THE_VALUE_AFTER_EncodedCommand'
[System.Text.Encoding]::Unicode.GetString([Convert]::FromBase64String($b64))
If PowerShell script block logging is on, event ID 4104 in Microsoft-Windows-PowerShell/Operational records the decoded script, which saves the decoding step. Anything beyond a browser start for an authorization address, such as downloads, new scheduled tasks or reads of credential files like auth.json, deserves an incident ticket. If you find that, treat every credential on the machine as exposed, including provider keys in auth.json, MCP tokens in mcp-auth.json, SSH keys and cloud CLI sessions.
Part D: if you build an MCP client or any tool that opens server supplied URLs
-
Check which
openyou ship.npm ls open --all npm explain openAnything below 11 lacks the PowerShell escaping fix. OpenCode chose 11.0.4 and forced transitive copies to the same version with an override:
{ "overrides": { "open": "11.0.4" } } -
Treat the upgrade as a partial fix. The
openREADME has said since 2021 that the package makes no security guarantees, and its maintainer closed issue #323 saying callers who pass untrusted input must sanitize it. Do not hand it raw strings from a remote server. -
Validate before you launch. Parse with the URL parser, allow only https (and http only for localhost redirects), and pass on only the normalized form produced by the parser. Show the host to the user before opening it if it differs from the server they configured.
function safeAuthUrl(raw: string, configuredServer: string): string { const u = new URL(raw); // throws on garbage if (u.protocol !== "https:") throw new Error("authorization URL must be https"); const server = new URL(configuredServer); if (u.hostname !== server.hostname) { // Different host is legal in MCP auth; require explicit user confirmation console.warn(`Sign in will open ${u.hostname}, not ${server.hostname}`); } return u.href; // normalized form only } -
Never build shell strings from URLs. Launch processes with an argument vector and no shell. That is the core recommendation from both the OpenCode and
mcp-remoteresearch. -
Test on Windows. Both bugs in this class only bit on Windows. A test that feeds hostile but well formed https URLs through your launcher on a Windows runner would have caught it.
Open questions
- What was the legacy system? OpenCode has not said what it was, how it was reached or why it still held provider keys.
- How many keys and users? 1.4% of an unknown total. Infosecurity Magazine notes OpenCode's CEO claimed about 13 million monthly active users in a July interview, but that is a product figure, not a Console figure.
- Were keys copied and used? OpenCode says "may have been exposed." User reports of unauthorized spend suggest misuse for at least some keys, but OpenCode has not confirmed it.
- What is the distillation link? OpenCode has not explained it.
- Did providers act? Only TechCrunch reports key blocking and refunds. No provider statement was found.
- Will the MCP flaw get a CVE? The researchers asked; Anomaly declined. Another CVE numbering authority could still assign one, but none had as of 22 October.
- Are other MCP clients affected? The bug class has now appeared in at least two MCP clients. Any client that opens a server supplied authorization URL through a shell on Windows is worth checking.
What would have helped
Practices any team can use
- One provider key per tool, with a hard cap at the provider. A key used only by your coding gateway, in its own OpenAI project or Anthropic workspace, with a hard spend limit, turns a stolen key into a bounded loss and makes it obvious which key to revoke.
- Expiring keys. OpenAI and Anthropic both support key expiry. A 90 day key that leaks is a smaller problem than one that lives forever.
- Provider side alerts. Budget alerts at the provider, not just in the gateway, because a thief calling the provider directly bypasses the gateway's budget.
- Know where every key lives. A short register of which keys are pasted into which hosted tools makes step 1 of Part A a lookup, not an archaeology project.
- An inventory of AI coding tools and versions on developer machines. When a fix ships without a CVE, the only way to find stragglers is to ask the machines. Device management queries for
opencode --version, or a simple login script that reports versions, would have answered "who is still on 1.18.32" in minutes. - An allowlist of remote MCP servers. Treat a remote MCP server as a dependency: owned by someone, reviewed, and removed when unused. Check that its domain is still held by the same owner.
- Treat server supplied fields as untrusted. For tool builders, the rule from both studies is simple: never pass a remote value to a shell, validate scheme and host, and test on Windows.
- Ask vendors to publish advisories. Silent fixes leave customers exposed. When you evaluate developer tools, ask whether the vendor publishes GHSA or CVE records for security fixes, including ones it considers out of scope. For background on how AI agents are changing attack paths, see our post on CERT-In's advisory on AI agent attack vectors.
Where Safeguard fits
Safeguard would not have prevented or detected either issue, and we want to be specific about why.
The Console breach. It happened inside a hosted service. Safeguard has no view into OpenCode's systems or into provider key stores, and nothing in Safeguard would have flagged the intrusion or the misuse of a key at OpenAI, Anthropic or Google.
The MCP flaw. Safeguard matches components against vulnerability databases. This issue has no CVE and no GHSA, and the open package issue was closed without an advisory, so vulnerability matching would not have raised either one. A globally installed tool on a developer laptop is also not part of a repository's SBOM unless you scan that machine or directory.
Here is the narrower part Safeguard can play.
Finding the bug class in your own code. Safeguard builds SBOMs from repositories, container images and SBOM files (safeguard scan --dir ., --image <name>, --sbom <file>, with JSON results under ./output), and the platform shows which projects contain a given component and version. If you build MCP clients, CLIs or internal tools, you can look up the open component across every project and see which still carry a version below 11. That turns Part D into a list. Our post on SBOM incident response walks through the method.
Making the change with approval. The Safeguard CLI's assistant can edit code and run commands on your machine, asking first in the default flow (/permissions offers Ask, Accept edits, Plan, Auto and Strict). You can ask it to bump open to 11.0.4, add the overrides entry, wrap your browser launch in a URL check, and run your tests, approving each step. It can also update the code that reads a renamed environment variable after a key rotation. The desktop and phone apps can send that work to a computer running the CLI and approve each command. In CI, safeguard exec runs the checks.
Fix pull requests where a fixed version exists. Autonomous remediation opens tested pull requests that move a dependency to a fixed version, once you switch it on. It is off by default. For an issue with no advisory, it will not start on its own; you would ask the CLI for the change instead.
Policies and gates. Platform policies and gates act on findings, so they help keep known vulnerable dependencies out during a hurried change. They do not act on issues with no advisory, and they do not inspect API keys.
Zero-Day Discovery and Gold
These are built for a different gap, and it is worth being exact about it.
- Zero-Day Discovery looks for previously unknown flaws before a CVE exists, in an agentic mode and a deterministic scanner mode, across seven package ecosystems. Findings are issued as SGZ advisories before they reach public CVE databases. A silently fixed npm bug is the kind of gap this capability is meant for. We do not claim that Zero-Day Discovery flagged this OpenCode issue or that an SGZ advisory existed for it. It also has nothing to say about the Console intrusion, which was a service breach, not a package flaw.
- Gold Open Source at gold.safeguard.sh is free and needs no login: searchable CVE intelligence with CVSS, EPSS, KEV status, affected and fixed versions and a recommended safe version, plus a free read API and a CI gate GitHub Action. Because this issue has no CVE, there is no public record for it to show.
- Gold Registry at registry.safeguard.sh is paid: hardened drop in components and container images held to zero exploitable critical or high CVEs, built to SLSA L3 or higher, signed with Sigstore, with evidence pages. An artifact loses its badge if it regresses. We make no claim that Gold carries a fixed build related to this incident.
The habit that carries over is speed. Teams that recover fastest know exactly what they run, including the tools on developer laptops, and can rebuild or reinstall from patched, signed components quickly. For the wider month, see October 2026 security incidents and what would have helped, and for a parallel lesson about provenance in npm, see the Tensorlake npm compromise.
Common mistakes
- Deleting the key from Console and stopping there. The key is still valid at the provider. Revoke it at OpenAI, Anthropic or Google.
- Relying on the Console budget. It only caps traffic through Console. A copied key used directly is capped only by provider side limits.
- Assuming no email means no risk. OpenCode says users without the email were not affected. If you are unsure which keys were ever linked, rotate; it costs minutes.
- Revoking before the replacement is live. All three providers recommend creating and deploying the replacement first. Revoking first breaks production during an incident.
- Waiting for a scanner to flag OpenCode. It will not, because there is no CVE. Check versions by hand.
- Upgrading Windows and forgetting WSL. WSL installs are separate binaries. Check each distribution.
- Trusting the URL scheme check. It was part of the fix, but the payload was a valid https URL. The
openupgrade is what closed it. - Leaving stale MCP servers configured. A server you added months ago and no longer use is still one discovery document away from your machine. Remove it and log out.
FAQ
Was my provider key exposed in the OpenCode Console breach?
OpenCode says the affected group is 1.4% of Console users, all of whom had an external OpenAI, Anthropic or Google key linked, and that affected users received an email titled "Action Required: Potential provider key breach." If you got that email, assume the key is exposed and rotate it. If you did not, OpenCode says you were not affected.
I only use the OpenCode CLI with my own keys. Do I need to rotate?
Not because of the Console breach. OpenCode co-founder Dax Raad said the CLI and desktop apps were not affected and that their keys never reach OpenCode; they are stored locally. You should still upgrade if you use Windows or WSL, because of the separate MCP flaw.
When did the exposure window start?
According to BleepingComputer's reading of OpenCode's email, 00:30 UTC on 17 October 2026. Review provider usage from at least 16 October to be safe.
Will I be refunded for unauthorized usage?
TechCrunch reports that OpenCode said refunds were underway and that OpenAI was refunding credits used in the attack. Neither OpenCode's full terms nor provider statements have been published. Export your usage and cost data for the window now so you have it for any claim.
Which OpenCode versions have the MCP flaw?
opencode-ai 1.0.137 through 1.18.32, on Windows and WSL only. Version 1.18.33, released 28 September 2026, fixes it. Version 1.0.137 is the release that added OAuth for remote MCP servers.
Is the MCP flaw being exploited?
No exploitation has been reported, and no indicators have been published, according to The Hacker News. The trigger requires a remote MCP server under an attacker's control and a sign in from the victim's machine.
Why is there no CVE?
The researchers asked for one. According to them, Anomaly said a malicious MCP server is outside its threat model, and OpenCode's security policy lists MCP server behaviour as out of scope. The fix shipped in a pull request described as a refactor. No other CVE numbering authority had assigned an ID as of 22 October.
Does upgrading open in my own project fully fix the bug class?
It closes the PowerShell expansion path that the researchers describe, and they call 11.0.4 the true fix. The package itself makes no security guarantees, so pair the upgrade with URL validation and never pass remote strings through a shell.
Are macOS and Linux users safe from the MCP flaw?
For this specific OpenCode issue, yes, according to the researchers and The Hacker News: on those systems the browser is opened without a shell. The earlier mcp-remote bug showed that limited execution is still possible on macOS and Linux in some designs, so validate URLs everywhere.
Is the Console breach related to the MCP flaw?
No. One is a breach of a hosted service; the other is a client side bug fixed weeks earlier. They happened to become public in the same week.
Fix it without waiting for upstream
The OpenCode client issue shows the second gap below in its sharpest form: the fix existed, but with no advisory, nothing told most users to take it. For the open source dependencies inside the tools you build yourself, such as the open package in an MCP client, you do not have to wait for anyone.
In incidents like this one, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.
1. Autonomous remediation: pull requests, not tickets
When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.
2. Gold Open Source: the safe version in seconds, free
gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.
3. Gold Registry: start from components that are already fixed
registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.
When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.
| Your situation | What to use |
|---|---|
| A fixed version exists | Autonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version |
| You need to know today whether you are affected | Gold Open Source lookup and "Am I affected?" checker, free and without login |
| You want vulnerable versions to stop shipping | The Gold scan GitHub Action in CI, plus Safeguard policies and gates |
| Upstream has no fix yet, or will not ship one | A custom Gold request; fork and patch (early access) |
| You want to start clean on new projects | Pull hardened components and images from Gold Registry |
One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.
See how Safeguard would have helped
None of these demos show the OpenCode incident. Each is a real Safeguard session, and the text says how the same flow applies here.
The first demo is a CLI session that fixes a lodash CVE: the assistant reads the finding and advisory, asks before each command, edits package.json, runs npm install and npm test with your approval, and pushes nothing. If you maintain an MCP client or internal CLI, you would open the same session in that repository and ask it to move open to 11.0.4, add the overrides entry and wrap the browser launch in a URL check, then run the tests. It asks before each edit and command.
Click through it at your own pace, or open it full screen.
The second demo is a desktop app session. The CLI session shows in the conversation list, you ask for work on your computer, pick the folder, then Approve or Deny each command and file edit, and it ends with an upgrade done and tests passing. After a key rotation, you could point the same flow at a service repository and ask it to find every place that reads the old provider key variable and switch it to the new secret name, approving each edit before it lands.
Click through it at your own pace, or open it full screen.
The third demo connects Claude to the Safeguard MCP server with OAuth and lets you choose which tools Claude can use. It shows what a remote MCP sign in should look like: a server you chose on purpose, a sign in page you recognise, and a deliberate decision about which tools the assistant may call. The OpenCode flaw is a reminder to apply the same care to every remote MCP server you add, in any client.
Click through it at your own pace, or open it full screen.
To try it on your own repositories, download Safeguard and follow the CLI documentation. For the full response pattern when a dependency goes bad, see our incident response playbook for a compromised dependency, and for how the Safeguard CLI handles approvals, see the Safeguard CLI as a security aware coding assistant.
Quick check
You removed your Anthropic key from your OpenCode Console workspace. Is the key safe now?
No. Removing it from Console does not revoke it, and Console budgets do not limit direct use. Deactivate the key in the Claude Console or with the Admin API ("status": "inactive"), then review usage for that key from 16 October onward.
A developer on Windows runs OpenCode 1.18.20 and your dependency scanner shows nothing. Are they safe?
No. Versions 1.0.137 through 1.18.32 are affected on Windows and WSL, and the issue has no CVE or advisory, so scanners that match vulnerability databases will not flag it. Upgrade to 1.18.33 or later and review the remote MCP servers with opencode mcp list.
Sources
- OpenCode GitHub release v1.18.33
- OpenCode pull request #51414: share a browser opener across opencode and tui
- OpenCode GitHub release v1.0.137
- OpenCode security policy and advisories
- OpenCode docs: MCP servers
- OpenCode docs: CLI
- OpenCode docs: Console
- Research write up: Open and shut, remote code execution in OpenCode via MCP OAuth
- open package issue #323: OS command injection on windows when opening urls
- open package releases
- GitHub advisory GHSA-6xpm-ggf7-wc3p (CVE-2025-6514, mcp-remote)
- Research on CVE-2025-6514 in mcp-remote
- Model Context Protocol specification: Authorization
- Anthropic docs: Admin API
- Anthropic docs: Usage and Cost API
- OpenAI docs: Spend limits
- OpenAI docs: Production best practices
- Google AI for Developers: Using Gemini API keys
- Google Cloud docs: Manage API keys
- The Hacker News: OpenCode Console breach may have exposed saved AI provider API keys
- The Hacker News: OpenCode flaw lets malicious MCP servers run code
- The Hacker News: Critical mcp-remote vulnerability (CVE-2025-6514)
- BleepingComputer: OpenCode hack exposes API keys amid AI distillation attacks
- TechCrunch: Hackers hit AI coding tool OpenCode, running up charges on users' AI accounts
- Infosecurity Magazine: OpenCode breach could affect OpenAI, Anthropic and Google keys
Last reviewed: 22 October 2026. This is a developing story; check the linked advisories for the latest status.