TL;DR

Between 07:35 and 21:45 UTC on 2026-08-31, an attacker used a stolen Cloudflare API key to add malicious origin IPs to the pool behind registry.coder.com, so a fraction of legitimate module pulls were served tampered Terraform modules that stole every credential in the provisioning environment and shipped them to a lookalike domain. Coder — a self-hosted cloud development environment used to provision workspaces for Claude Code, Codex, and other AI coding agents — is the CDN-hijack sibling of the Coder AI-Bridge OIDC release: this time the bug was not in Coder's code but in the delivery path in front of it. Fixed by upgrading to 2.37.0 / 2.36.4 / 2.35.7 / 2.34.9, which purge the poisoned modules from cache. If your Coder pulled a module during the window, treat every credential the provisioner could reach as exfiltrated.

What happened

Coder disclosed the incident on 2026-09-04 (Coder blog) alongside GHSA-vx42-ghc9-gw65 (published 2026-09-01, Critical, CVSS 9.0, no CVE). The chain, per the advisory:

  1. An unauthorized actor obtained a Cloudflare API key belonging to Coder and used it to add attacker-controlled origin IPs to the server pool for registry.coder.com, so Cloudflare load-balanced a share of real requests to the attacker's server.
  2. The attacker's server returned tampered copies of legitimate Coder registry modules. The tamper was a single injected Terraform data "external" "telemetry" block that runs ${path.module}/dlp-docker.sh — a legitimate Terraform construct that executes a script during provisioning with the privileges of the provisioning process.
  3. The script harvested and exfiltrated provisioner environment variables, cloud and AI-tooling API keys, CI/CD credentials, config-file secrets, terminal history, user OIDC tokens, SSH keys, external-auth tokens, and (where the provisioner ran inside coderd) Coder database passwords.
  4. Stolen data went out over POST http://www.coder-infra[.]com/cli/check with the loot in an X-CLI-Token header. The lookalike domain was registered 2026-08-28, three days before the window.

The window was ~14 hours; the lookalike was pre-staged; only a fraction of pulls were poisoned because the malicious origins shared the pool with the real ones. Coder states its own codebase and Google Cloud infrastructure were not compromised and it found no evidence customer data it maintains was affected — but it cannot conclusively identify every affected deployment, and notes its lock file does not track remote modules, so version-pinning would not have caught this. Independent coverage: BleepingComputer, eSecurity Planet, CSA Lab Space.

Why this repo cares: Coder is where a lot of teams run their AI coding agents, so a poisoned provisioning module inherits AI provider keys and MCP credentials alongside the usual cloud/CI secrets. This is the same shape as the Coder AI-Bridge coordinated release (dev-environment platform as a credential hub) and the same delivery-layer lesson as any CDN/registry hijack: a trusted download endpoint is part of your supply chain even when the vendor's source is clean.

Am I affected?

You are potentially affected if a Coder deployment pulled a registry module during 2026-08-31 07:35–21:45 UTC.

# Coder version
coder version

# Provisioner logs: the tampered module leaves this sentinel string
grep -r 'data.external.telemetry' /var/log/coder* 2>/dev/null
# ...and the injected script name
grep -rn 'dlp-docker.sh\|dlp.sh' /var/log/coder* 2>/dev/null

# DNS / firewall / VPC flow logs: any lookup or connection to the exfil domain
#   is a confirmed-compromise signal (defanged; do not resolve or visit)
#   coder-infra[.]com  (and subdomains)  ->  199.91.220[.]205

Coder's advisory ships SQL queries to list templates, template versions, and workspaces that fetched cached modules during the window, plus a deletion query to purge them.

IOCs

Type Value
GHSA GHSA-vx42-ghc9-gw65 (Critical, CVSS 9.0, no CVE)
Incident window 2026-08-31 07:35–21:45 UTC
Exfil domain coder-infra[.]com (registered 2026-08-28), endpoint /cli/check, X-CLI-Token header
Malicious origin IP 199.91.220[.]205
Provisioner-log sentinel data.external.telemetry; scripts dlp-docker.sh, dlp.sh
Affected Coder < 2.37.0 (deployments that pulled a module in the window)
Fixed 2.37.0, 2.36.4, 2.35.7, 2.34.9 (purge cached poisoned modules)
Data stolen cloud + AI-provider API keys, CI/CD creds, OIDC tokens, SSH keys, external-auth tokens, terminal history, coderd DB passwords

If you are affected

  1. Upgrade to 2.37.0 / 2.36.4 / 2.35.7 / 2.34.9 (or later) and run Coder's cache-purge SQL so poisoned modules cannot be re-served from cache.
  2. If you cannot rule out a pull during the window, rotate every credential the provisioning process could reach: cloud provider keys, CI/CD credentials, SSH keys, OIDC tokens, external-auth tokens, and — because Coder provisions AI workspaces — every AI provider / MCP credential wired into a template. See playbooks/rotating-cloud-credentials.md.
  3. Search firewall / DNS / VPC flow logs for coder-infra[.]com and 199.91.220[.]205; a hit is confirmation, not suspicion.
  4. If a workspace agent or its live credentials may have been used: playbooks/if-your-local-ai-agent-was-exploited.md.

Update 2026-09-20 — an earlier, unrelated Coder bug worth knowing: a workspace-proxy hostname prefix match let an attacker's domain collect app-scoped API keys (GHSA-h58h-qvv5-xvwg, CVSS 7.7, 2026-08-10; reported by Anthropic's security team)

Three weeks before the registry compromise, Coder published a batch of five advisories on 2026-08-10 that no sweep here had logged. The one that matters for workspaces exposed through proxies: GetWorkspaceProxyByHostname matched proxy hostnames with a prefix pattern rather than an exact host, so a domain that was merely a string prefix of a real proxy URL — the advisory's example: syd.co matching syd.coder-proxy.example.com — was treated as a trusted proxy. An attacker who got an authenticated user to click a crafted auth-redirect link could intercept an application-scoped API key and replay it against the genuine proxy to reach the victim's workspace apps. Affected v2.35.0–2.35.3, v2.34.0–2.34.7, v2.33.0–2.33.11 and everything before v2.29.20; fixed v2.35.4 / v2.34.8 / v2.33.12 / v2.29.20 (the pattern now requires a string end, port delimiter or path separator after the host). Deployments that do not use workspace proxies are not affected. No CVE. Credited to the Anthropic Security Team (ANT-2026-FXER0JGJ) and Adam Korczynski (Ada Logics) — a data point that AI-vendor security teams are auditing the cloud-dev-environment layer their own agents run in. The same day's batch also covered an unauthenticated agent debug manifest exposing environment variables across workspace users (Low), user-level ACL grants bypassing org membership (Moderate), cross-org Terraform module file disclosure via the provisioner DownloadFile RPC (Moderate) and a workspace ACL endpoint exposing group-member PII (Moderate). If you are on a fix line below the registry-incident versions above (2.37.0 / 2.36.4 / 2.35.7 / 2.34.9), you are past this one too; if you pinned lower, the proxy bug is a second reason to move.

Update 2026-10-13 — a third Coder advisory: GCE instance-identity tokens accepted without an audience check (GHSA-24vh-q7rg-243w, CVSS 6.5)

Coder published GHSA-24vh-q7rg-243w on 2026-10-13: the POST /api/v2/workspaceagents/google-instance-identity endpoint verified Google Compute Engine identity tokens but did not check the aud claim, so an unexpired token issued for any other relying party could be replayed to obtain that workspace agent's session token (CWE-441, CVSS 3.1 6.5, AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:N). Signature and expiry are still checked, so forgery is not possible, and the impact is one agent's credential until the workspace's next build. Fixed in 2.38.0 and backported to 2.37.4, 2.36.7, 2.35.9, 2.34.12 and 2.29.21; the fix requires aud to equal coder, so custom clients must request audience=coder. Workaround: switch affected templates to auth = "token" and restart workspaces, and do not log or forward GCE identity tokens from workspace VMs. Reported by matte1782 with thanks to a customer security team. No CVE on the page. Relevant here because the agent token is what a Coder workspace running Claude Code or Codex presents to the control plane, and because a token minted for another GCP service was enough.

Update 2026-10-18 — VulnCheck assigned eleven CVE ids to Coder advisories on 2026-10-17, most dated June to August 2026 and two older (CVE-2024-58398 and CVE-2025-71435); the proxy prefix-match bug is CVE-2026-111927, and three of the August advisories were reported by Anthropic's security team

VulnCheck published eleven Coder records on 2026-10-17, each referencing a vendor advisory that still printed "No known CVE" when re-read on 2026-10-18. None describes a new bug; the ids are what scanners and govulncheck match on, so a deployment pinned below the fix lines now shows up as vulnerable where it did not before. The records, with the vendor page each cites and the vendor's fix lines:

CVE (VulnCheck, 2026-10-17) Vendor advisory Vendor date VulnCheck score (4.0 / 3.1) Fixed in
CVE-2026-111927 GHSA-h58h-qvv5-xvwg, workspace-proxy hostname prefix match (the 2026-09-20 update above) 2026-08-10 8.7 / 7.7; vendor 7.7 2.35.4, 2.34.8, 2.33.12, 2.29.20
CVE-2026-111926 GHSA-73wg-wxvv-9r4j, unauthenticated agent debug server on 127.0.0.1:2113 returns the manifest with template-provided environment variable values to any Unix user in the workspace 2026-08-10 4.8 / 3.3; vendor 3.3 2.34.8 (values are now redacted, names kept)
CVE-2026-111928 GHSA-7v78-w67v-pm2g, per-user ACL entries in policy.rego not checked against organisation membership, and not scrubbed on removal 2026-08-10 5.3 / 5.4 2.34.8
CVE-2026-111929 GHSA-hrhj-hpwc-9hmc, provisioner daemon DownloadFile RPC serves other organisations' cached Terraform module archives to an org-scoped provisioner key with a known file UUID 2026-08-10 6.0 / 5.3 2.34.8
CVE-2026-111930 GHSA-cvrm-2xxr-hpcv, GET /api/v2/workspaces/{id}/acl returns group members' emails, login types and timestamps to anyone with workspace use access 2026-08-10 5.3 / 4.3 2.34.8
CVE-2026-111931 GHSA-98qx-9p2x-c4wh, open redirect in the workspace-app subdomain proxy's API-key exchange (a path beginning with two slashes becomes a scheme-relative redirect); needs wildcard subdomain routing 2026-08-10 5.3 / 4.3 2.34.8, 2.35.0
CVE-2026-111934 GHSA-vprw-xcrv-287h, ExtractRealIPAddress took the leftmost X-Forwarded-For value, so per-IP rate limits on login, one-time passcode and password validation could be bypassed and audit_logs.ip falsified; only when Coder is configured to trust that header 2026-08-11 6.3 / 3.7 2.34.7, 2.35.0
CVE-2026-111932 GHSA-h58c-xccx-75m3, stored HTML injection through the ApplicationName and LogoURL appearance settings (Owner role required) 2026-08-20 4.8 / 3.4 2.34.2, 2.33.8, 2.32.7, 2.29.17
CVE-2026-111933 GHSA-8fxq-53rx-ph5f, user enumeration: an empty stored password hash is compared against a placeholder, so one fixed password distinguishes 403 from 401 and reveals SSO-only accounts 2026-08-20 6.3 / 3.7 2.34.2, 2.33.8, 2.32.7, 2.29.17
CVE-2024-58398 GHSA-wcx9-ccpj-hx3c, open redirect through the login page's redirect parameter not fetched 5.3 / 4.3 2.16.1, 2.15.3, 2.14.4
CVE-2025-71435 GHSA-3rw9-wmc8-8948, an OIDC session with no refresh token keeps its API key cookie alive past token expiry through regular use not fetched 2.3 / 4.2 2.23.0

Three of the August advisories credit Anthropic's Security Team by reference number: the debug manifest (ANT-2026-22461), the open redirect (ANT-2026-22456) and the X-Forwarded-For parsing (ANT-2026-22432), in addition to the prefix-match credit already recorded above. The 2026-10-17 batch is a second instance of the shape this file's 2026-09-20 update described: Coder's own tab is where the bugs appear, months before any CVE exists, and the CVE arrives when a research CNA decides to issue one. The score column shows why the vendor's rating should be read alongside the record's: VulnCheck's 4.0 scores run higher than the vendor's 3.1 scores on the same text, by one point on the prefix-match bug and by two and a half on the user-enumeration one, with no change in the description. Nothing in the batch moves this file's status; every id is fixed in 2.34.8 or earlier, and the registry-incident fix lines above (2.37.0, 2.36.4, 2.35.7, 2.34.9) are past all of them.

Prevention

→ prevention/supply-chain-attack-surface.md — a vendor's download/registry endpoint is part of your supply chain; a clean source repo does not make the delivery path clean. → prevention/ci-cd-hardening.md — scope provisioning credentials as narrowly as possible; an AI-agent workspace needs its model-provider/MCP keys, not the full provisioning credential set. → prevention/credential-hygiene.md — short-lived tokens over long-lived keys so a 14-hour exposure window is a rotation, not a standing breach.

Published on coder/coder on 2026-10-27 (no CVE; CVSS 3.1 7.7 AV:N/AC:H/PR:L/UI:R/S:C/C:H/I:H/A:N, CWE-201): the dashboard replaced the $SESSION_TOKEN placeholder in external workspace-app URLs with a newly minted API key without checking whether the app belonged to a sub-agent. Sub-agent apps are registered at runtime by code in the workspace, such as a devcontainer or an AI agent, so a sub-agent could register an app using an allowed custom protocol such as vscode: with the placeholder and an attacker-chosen destination, and when the owner clicked it the dashboard minted a full-access key and opened the URL with it; the attacker controls the app's name and icon. The coder open app CLI already refused this for sub-agents (GHSA-v54h-cp2w-9x4g); the dashboard did not. Affected 2.24.0 before 2.29.23, 2.30.0 before 2.34.14, 2.35.0 before 2.36.0 (end of life, no patch), 2.36.0 before 2.36.9, 2.37.0 before 2.37.6, 2.38.0 before 2.38.2. Fix PR #31208: no substitution for sub-agent apps, and for other external apps only when the link opens a known Coder IDE handler and points at the same deployment. Workaround: do not click external apps under devcontainer or other sub-agents unless you trust the workspace's code. Credits a customer security team and manus-pi; fix by EhabY. For this corpus the point is that an AI agent running inside the workspace is exactly the sub-agent the advisory describes. Also on the tab since the last read: GHSA-373r-678h-hjc6 (2026-10-21, Moderate), an encoded path traversal in the AI Gateway passthrough that let users reach unintended upstream provider endpoints, still without a CVE.

Update 2026-10-29 — the GCE instance-identity bug is CVE-2026-118687 (VulnCheck, 2026-10-28; CVSS 4.0 8.3, 3.1 6.5)

VulnCheck published CVE-2026-118687 on 2026-10-28 for GHSA-24vh-q7rg-243w (the 10-13 update above): "Coder before 2.29.21, 2.30.0 before 2.34.12, 2.35.0 before 2.35.9, 2.36.0 before 2.36.7, and 2.37.0 before 2.37.4 does not validate the audience claim of GCE instance-identity JWTs at the POST /api/v2/workspaceagents/google-instance-identity endpoint." The ranges match the vendor's backports. Scores: VulnCheck CVSS 4.0 8.3 (AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:L/VA:N) and CVSS 3.1 6.5, the same 3.1 vector the vendor printed. The vendor page said no CVE on 10-13; the id now exists, fifteen days later, from a research CNA. Credit matte1782.

Sources for this update: CVE Services — CVE-2026-118687 — fetched 2026-10-29: CNA VulnCheck, published 2026-10-28, the five ranges, both scores, the GHSA reference, the credit.

Update 2026-10-30 — three more Coder advisories on 2026-10-29 (read-only roles could fetch an external agent's token; scoped keys minted unscoped keys; Web Push read exhausted coderd memory); fixed 2.38.4, 2.37.8, 2.36.11, 2.34.16, 2.29.24

Three vendor advisories published on coder/coder on 2026-10-29, all Moderate, all "No known CVE" when read, all fixed in the same five versions.

  • GHSA-9frj-7f83-x984 (6.5, PR:H, CWE-200/863). GET /api/v2/workspaces/{workspace}/external-agent/{agent}/credentials returned the agent token and the start command to anyone with read access to the workspace, while every other agent-level route required ssh access. Premium deployments using external workspaces (coder_external_agent) were affected; Template Admins, Organization Admins and the Owner role with owner workspace access disabled were among the roles that could read another user's token, then read the owner's Git SSH key and external auth tokens, the agent manifest with its environment variables, and connect as the agent to receive the owner's sessions. The fix requires ssh access and returns 404 otherwise, which removes some admins' ability to fetch install commands for other users' external workspaces. Reported by Habib0x0, @jondavid-black and a customer security team.
  • GHSA-x3gf-xv6p-56hf (6.8, AC:H, CWE-266). A scoped API key or OAuth2 access token that could create API keys created them without inheriting its own scopes, allow list or expiry; a request with no scopes defaulted to coder:all, so a limited token minted a full-access key, for other users too when the caller was an Owner. The fix makes new keys inherit the creator's scopes and allow list, rejects escalation with 403 and caps expiry; /oauth2/authorize now returns invalid_scope in restricted cases, a behaviour change for clients that relied on the default. Reported by a customer security team and Muted Cybersecurity.
  • GHSA-64xh-rgcx-gg65 (6.5, PR:L, CWE-400/770). Web Push delivery read the push endpoint's whole response into memory with no size limit or timeout, and any authenticated user chooses that endpoint when subscribing, so one subscription pointed at a server that never stops sending took coderd down and could again after each restart. Web Push is on by default since 2.33.0; 2.21.0 to 2.32.x are affected only with the web-push experiment enabled. The fix caps reads and headers at 64 KiB and adds a 30-second client timeout. Credited to Anthropic's Security Team (ANT-2026-24Z4555M) and Adam Korczynski of Ada Logics.

Each advisory lists six affected ranges and five patched versions. Shared by all three: >= 2.38.0 < 2.38.4, >= 2.37.0 < 2.37.8, >= 2.36.0 < 2.36.11, >= 2.30.0 < 2.34.16 and >= 2.35.0 < 2.36.0 (end of life, no fix). The sixth range ends at 2.29.24 and starts where each bug was introduced: >= 2.26.0 < 2.29.24 for the external-agent token, >= 2.28.0 < 2.29.24 for the scoped keys, >= 2.21.0 < 2.29.24 for Web Push. The first two are the same shape as GHSA-2x8w-q434-f76p above: a credential handed to a caller the role model did not mean to give it to, in a product whose workspaces run AI agents with the owner's keys. The vendor tab now carries four October advisories; CVE ids may follow from VulnCheck as they did on 10-17 and 10-28.

Sources for this update: GHSA-9frj-7f83-x984, GHSA-x3gf-xv6p-56hf and GHSA-64xh-rgcx-gg65 — fetched 2026-10-30: published Oct 29, 2026, the scores and vectors, the six affected ranges and five patched versions, the mechanisms, fixes and credits as summarised; coder/coder — security advisories — fetched 2026-10-30: the three 10-29 rows beside the 10-27 and 10-21 ones.

Sources