Skip to main content

Coder CVE-2026-45796

MEDIUM
Server-Side Request Forgery (SSRF) (CWE-918)
2026-05-19 https://github.com/coder/coder GHSA-686c-7vgv-v3fx
6.5
CVSS 3.1 · Vendor: https://github.com/coder/coder
Share

Severity by source

Vendor (https://github.com/coder/coder) PRIMARY
6.5 MEDIUM
AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N

Primary rating from Vendor (https://github.com/coder/coder) · only source for this CVE.

CVSS VectorVendor: https://github.com/coder/coder

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
Low
Integrity
Low
Availability
None

Lifecycle Timeline

2
Source Code Evidence Fetched
May 19, 2026 - 20:17 vuln.today
Analysis Generated
May 19, 2026 - 20:17 vuln.today

DescriptionCVE.org

Summary

Unauthenticated semi-blind Server-Side Request Forgery (SSRF) via the Azure instance identity endpoint (POST /api/v2/workspaceagents/azure-instance-identity). An external attacker can force the Coder server to issue HTTP GET requests to arbitrary internal or external hosts by submitting a crafted PKCS#7 signature. The server does not return the target's response body, but error messages in the API response reveal whether the target is reachable and what type of failure occurred.

Details

The POST /api/v2/workspaceagents/azure-instance-identity endpoint accepts a PKCS#7 signature without authentication. During certificate chain verification, azureidentity.Validate() iterates over the signer certificate's IssuingCertificateURL extension and fetches each URL using http.DefaultClient with no host restriction, no private-IP blocking, and no response-size limit.

An attacker crafts a self-signed certificate whose Common Name matches *.metadata.azure.com (passing the allowedSigners regex) and whose IssuingCertificateURL points to an attacker-chosen target. The server fetches that URL and feeds the response body into x509.ParseCertificate. The parsed result is discarded, but the wrapped error string is returned verbatim in the JSON response via Detail: err.Error(). Connection-level errors ("connection refused", "i/o timeout", DNS failures) and certificate-parse errors give the attacker enough signal to infer host reachability and port state without seeing the actual response content.

Root causes:

  1. No allowlist on IssuingCertificateURL hosts. Any URL was accepted.
  2. http.DefaultClient was used. It follows redirects and connects to private, link-local, and loopback addresses.
  3. Unbounded io.ReadAll on the response body (memory exhaustion vector).
  4. Raw err.Error() was returned in the JSON response, leaking internal HTTP client errors to the caller.

Impact

This is a semi-blind SSRF: the server makes the outbound request but the HTTP response body is consumed by x509.ParseCertificate and never returned to the attacker.

  • Internal network reconnaissance. The attacker can map internal hosts and ports by observing error differentiation in the API response: "connection refused" (port closed), "i/o timeout" (host unreachable or firewalled), DNS failure (host does not exist), or certificate-parse error (port open and responding). This enables systematic scanning of the internal network from the Coder server's vantage point.
  • Requests to sensitive endpoints. The server can be directed to hit cloud metadata services (e.g. http://169.254.169.254/), internal admin interfaces, or other services. The attacker cannot read the response content, but the request itself may have side effects depending on the target.
  • Error-based information disclosure. Wrapped Go HTTP client errors in the Detail field expose internal hostnames, IP addresses, port numbers, and network topology details.
  • Memory exhaustion. The unbounded io.ReadAll on the response body allows an attacker to point IssuingCertificateURL at a large resource, forcing the server to buffer it entirely in memory.

Patches

Fixed in #25274 (commit 57b11d405):

The fix was backported to all supported release lines:

Release linePatched version
2.33v2.33.3
2.32v2.32.2
2.31v2.31.12
2.30v2.30.8
2.29v2.29.13
2.24 (ESR)v2.24.5

Workarounds

If the Azure identity-auth mechanism is not being used then restrict access to the corresponding endpoint (/api/v2/workspaceagents/azure-instance-identity) using ingress firewall and/or proxy ACLs.

Recognition

We'd like to thank Ben Tran of calif.io and Anthropic's Security Team (ANT-2026-22447) for independently disclosing this issue!

AnalysisAI

Unauthenticated semi-blind Server-Side Request Forgery in Coder's Azure instance identity endpoint allows any remote attacker to force the Coder server to issue HTTP GET requests to arbitrary internal or external hosts, enabling internal network reconnaissance, cloud metadata service probing (e.g., 169.254.169.254), and error-based information disclosure of network topology. The vulnerability exists across all supported Coder release lines prior to v2.29.13/v2.30.8/v2.31.12/v2.32.2/v2.33.3/v2.24.5 (ESR), and has been patched in GitHub PR #25274. No public exploit code has been identified at time of analysis, and the vulnerability is not listed in the CISA KEV catalog.

Technical ContextAI

The vulnerability resides in Coder's Go-based server (pkg:go/github.com_coder_coder_v2), specifically in the azureidentity.Validate() function (coderd/azureidentity/azureidentity.go). The affected endpoint POST /api/v2/workspaceagents/azure-instance-identity processes PKCS#7 signatures as part of Azure VM identity attestation. During certificate chain verification, the code iterates over the signer certificate's X.509 IssuingCertificateURL extension - a standard AIA (Authority Information Access) field - and fetches each URL using Go's http.DefaultClient. This client follows HTTP redirects, resolves to private and link-local IP ranges (including RFC 1918, 169.254.0.0/16, and loopback), imposes no timeout, and reads the response body with unbounded io.ReadAll. The allowedSigners regex only validated that the certificate Common Name matched *.metadata.azure.com, not the AIA URLs, creating the bypass path. CWE-918 (Server-Side Request Forgery) is the root cause class, compounded by CWE-200 (Information Exposure) via verbatim err.Error() output in the JSON Detail field.

RemediationAI

Upgrade Coder to a patched release immediately: v2.33.3, v2.32.2, v2.31.12, v2.30.8, v2.29.13, or v2.24.5 (ESR), per https://github.com/coder/coder/releases. The fix (PR #25274, commit 57b11d405) introduces an explicit host allowlist restricting IssuingCertificateURL fetches to www.microsoft.com and cacerts.digicert.com only, replaces http.DefaultClient with a custom HTTP client that enforces a 5-second timeout, blocks all private/link-local/loopback IP ranges (including RFC 1918, 169.254.0.0/16, 100.64.0.0/10, and others) with anti-DNS-rebinding protections, caps response body reads at 1 MiB, and strips internal error details from the API response. If upgrading immediately is not possible, the primary workaround is to block access to the endpoint POST /api/v2/workspaceagents/azure-instance-identity via ingress firewall rules or reverse proxy ACLs - this is safe if Azure instance identity authentication is not in use, with the trade-off of breaking Azure VM workspace agent registration for any deployments that do rely on it. The advisory is published at https://github.com/coder/coder/security/advisories/GHSA-686c-7vgv-v3fx.

Share

CVE-2026-45796 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy