Safeguard
Supply Chain Security•

OpenCode Console Key Breach and MCP OAuth RCE: What to Do Now

OpenCode Console provider keys may have leaked, and a silent fix closed a Windows MCP sign in RCE. Rotate stored keys and upgrade OpenCode to 1.18.33.

Safeguard Security Team
45 min read

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 breachMCP OAuth sign in command injection
What it isUnauthorized access to a legacy OpenCode system that held provider keys saved in ConsoleA remote MCP server can make OpenCode run commands on Windows or WSL during OAuth sign in
Who is affectedAbout 1.4% of Console users, all with an external provider linked, according to OpenCodeUsers of opencode-ai 1.0.137 through 1.18.32 on Windows or WSL who sign in to a remote MCP server
Fixed byRevoking the key at OpenAI, Anthropic or GoogleUpgrading to 1.18.33 (28 September 2026)
CVENone (service incident)None requested or issued
Your first commandCheck 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 timeEventSource
18 Oct 2023Issue #323, "OS command injection on windows when opening urls", is opened against the open packagesindresorhus/open issue #323
9 Jul 2025Advisory GHSA-6xpm-ggf7-wc3p (CVE-2025-6514) published for the same bug class in mcp-remote, fixed in 0.1.16GitHub advisory database
12 Nov 2025open issue #323 closed as "not planned"sindresorhus/open issue #323
15 Nov 2025open v11.0.0 released, including "Fix PowerShell argument escaping"open releases page; research write up gives the year
7 Dec 2025OpenCode commit 509e43d6 adds a call that opens the OAuth authorization URL with openResearch 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 2026MCP flaw reported privately through a GitHub security advisoryResearch write up
14 Sep (page shows no year; after v11.0.0)open v11.0.4 releasedopen releases page
24 Sep 2026OpenCode publishes GHSA-632h-h47v-g4x4, an unrelated High severity advisory, showing advisories are used for other issuesOpenCode security page
25 Sep 2026Researchers follow up; Anomaly says malicious MCP servers are outside its threat model; researchers ask for a CVEResearch 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 29f07e0cOpenCode 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 securityOpenCode GitHub release v1.18.33
4 Oct 2026Research report publication date as given in the write up's own timelineResearch write up
16 Oct 2026, nightIntruder reaches a legacy OpenCode systemOpenCode email via Infosecurity Magazine; The Hacker News
17 Oct 2026, 00:30 UTCEarliest possible exposure of affected keys, per OpenCode's emailBleepingComputer
17 Oct 2026, morningEmails titled "Action Required: Potential provider key breach" go out; OpenCode posts on XThe Hacker News; TechCrunch
18 Oct 2026Raad says attackers had been trying to get in for about 48 hoursThe Hacker News
19 Oct 2026, 12:28 PDTTechCrunch publishes, reporting provider key blocks and refundsTechCrunch
19 Oct 2026, 13:27 (page time)BleepingComputer publishes, citing the 00:30 UTC exposure windowBleepingComputer
19 Oct 2026MCP research write up page dated 19 Oct; The Hacker News and Infosecurity Magazine cover the Console breachResearch write up; The Hacker News; Infosecurity Magazine
22 Oct 2026The Hacker News covers the MCP flawThe Hacker News

Who is affected

GroupConsole breachMCP flawWhat to do
Console workspace with an external OpenAI, Anthropic or Google key linked, and you got the emailYes, according to OpenCodeDepends on your OpenCode version and platformRotate every linked provider key now and review usage from 16 October
Console workspace with a linked key, no emailOpenCode says not affectedDependsRotate anyway if you want certainty; it costs little
Console user with only OpenCode pay as you go credits, no linked providerNot in the affected group as describedDependsNo key rotation needed for this incident
OpenCode CLI or desktop user with keys in local auth.jsonNot affected, per OpenCodeYes if on Windows or WSL and running 1.0.137 through 1.18.32Upgrade; check MCP servers
OpenCode on macOS or Linux (not WSL)Not affected by the client bugNot affected, per the researchersUpgrade anyway for other fixes
Teams building their own MCP client that calls open on server supplied URLsNot relatedSame bug class may applyCheck your open version and URL handling

Affected and fixed versions

ComponentAffectedFixedPlatformSource
opencode-ai (npm)1.0.137 through 1.18.321.18.33, released 28 September 2026Windows and WSL onlyResearch write up; The Hacker News
open (npm), as used by OpenCode10.1.2 (pinned by OpenCode)OpenCode moved to 11.0.4Windows and WSL code pathOpenCode PR #51414
open (npm), upstreamReleases before 11.0.0 lack the escaping fix11.0.0 "Fix PowerShell argument escaping"; the researchers credit 11.0.4's single quoting as the real fixWindowsopen releases; research write up
mcp-remote (npm), related bug class0.0.5 through 0.1.150.1.16Full command execution on Windows; limited on macOS and LinuxGHSA-6xpm-ggf7-wc3p
OpenCode ConsoleLegacy system breached 16 to 17 OctoberService side; your fix is key revocation at each providerHostedOpenCode 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

FieldValueSource
ServiceOpenCode Console, the optional hosted gateway and workspace serviceOpenCode docs
System reached"a legacy system that we were in the process of decommissioning"OpenCode email quoted by Infosecurity Magazine
Date of intrusionNight of 16 October 2026The Hacker News; Infosecurity Magazine
Earliest possible key exposure17 October 2026, 00:30 UTCOpenCode email per BleepingComputer
Data at riskThird party provider keys saved in Console workspaces: OpenAI, Anthropic, GoogleThe Hacker News
Share of users1.4% of Console users, all with an external provider linkedOpenCode statement, multiple outlets
Notification subject"Action Required: Potential provider key breach"The Hacker News
Status languageKeys "may have been exposed"; incident described as ongoing on 17 OctoberThe Hacker News
Attack framing"related to a large-scale distillation attack"OpenCode statement
Duration of attemptsAbout 48 hours, per RaadThe Hacker News; TechCrunch
Not affectedOpenCode CLI and desktop apps, which store keys locally in SQLiteRaad, via The Hacker News and TechCrunch
Published indicators of compromiseNoneNo 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

FieldValueSource
Packageopencode-ai on npm, published by Anomaly (anomalyco)Research write up
CVENone requested or issuedResearch write up; The Hacker News
GHSANone for OpenCode. GHSA-6xpm-ggf7-wc3p cited in the write up belongs to mcp-remote CVE-2025-6514Research write up; GitHub advisory database
WeaknessCWE-78 (OS command injection), secondary CWE-88 (argument injection)Research write up
Proposed CVSS 3.1CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H, 9.8 CriticalResearch write up
Related CVECVE-2025-6514, mcp-remote, CVSS 3.1 9.6, AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:HGitHub advisory database
ExploitationNo signs of exploitation reported; no indicators publishedThe Hacker News
Vendor positionMalicious MCP servers are outside the threat model; "MCP server behavior" out of scope in SECURITY.mdResearch 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:

  1. It bumped open from 10.1.2 to 11.0.4, moved the dependency into @opencode-ai/core, and added a root overrides entry so transitive copies pulled in by storybook and @hey-api/openapi-ts resolve to the same version.
  2. It added openUrl(input) in a new @opencode-ai/core/open module. The function parses the target, launches only http: and https: URLs and passes the normalized href to open. Tests in packages/core/test/open.test.ts cover unparseable strings, file:, javascript:, custom schemes and UNC paths.
  3. It added the same http and https check inside the MCP OAuth provider's redirectToAuthorization method, with tests in packages/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

ItemValueSource
Local provider credentials~/.local/share/opencode/auth.jsonOpenCode CLI docs
Stored MCP OAuth tokens~/.local/share/opencode/mcp-auth.jsonOpenCode MCP docs
Config filesopencode.json or opencode.jsonc, servers under the mcp keyOpenCode MCP docs
Remote server entry"type": "remote", url, optional headers, enabled, timeout (default 5000 ms), oauthOpenCode MCP docs
Disable automatic OAuth"oauth": falseOpenCode MCP docs
Inventory commandsopencode --version, opencode mcp list, opencode mcp auth list, opencode mcp debug <name>, opencode mcp logout <name>OpenCode CLI and MCP docs
Upgrade commandopencode upgrade, or opencode upgrade <version> with --method for curl, npm, pnpm, bun or brewOpenCode 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

  1. 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.

  2. 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.

  3. Revoke the old key at the provider. Removing it from Console is not enough.

  4. Update every consumer. CI secrets, .env files, 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
    
  5. 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.

  6. 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

  1. Find every install. On each Windows machine, in PowerShell:

    opencode --version
    where.exe opencode
    npm ls -g opencode-ai
    wsl.exe -l -v
    

    Then inside each WSL distribution:

    command -v opencode && opencode --version
    npm ls -g opencode-ai 2>/dev/null
    

    Anything from 1.0.137 through 1.18.32 is affected on these platforms.

  2. Upgrade. Run opencode upgrade, or pin a version with opencode upgrade v1.18.33 (or a later version) and the --method flag that matches how it was installed. For npm installs, npm install -g opencode-ai@latest also works. Run opencode --version again to confirm.

  3. List remote MCP servers and their auth state.

    opencode mcp list
    opencode mcp auth list
    

    For 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.json or opencode.jsonc, in both the project and your global config.

  4. Clear tokens for servers you remove. Run opencode mcp logout <name>. Stored MCP OAuth tokens live in ~/.local/share/opencode/mcp-auth.json.

  5. Turn off automatic OAuth where you do not need it. If a server uses API key headers, set "oauth": false on its entry so a 401 cannot start a browser flow.

  6. 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 auth against 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

  1. Check which open you ship.

    npm ls open --all
    npm explain open
    

    Anything 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"
      }
    }
    
  2. Treat the upgrade as a partial fix. The open README 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.

  3. 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
    }
    
  4. 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-remote research.

  5. 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 open upgrade 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 situationWhat to use
A fixed version existsAutonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version
You need to know today whether you are affectedGold Open Source lookup and "Am I affected?" checker, free and without login
You want vulnerable versions to stop shippingThe Gold scan GitHub Action in CI, plus Safeguard policies and gates
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch (early access)
You want to start clean on new projectsPull 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

Last reviewed: 22 October 2026. This is a developing story; check the linked advisories for the latest status.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.