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.
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:
IssuingCertificateURL hosts. Any URL was accepted.http.DefaultClient was used. It follows redirects and connects to private, link-local, and loopback addresses.io.ReadAll on the response body (memory exhaustion vector).err.Error() was returned in the JSON response, leaking internal HTTP client errors to the caller.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.
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.Detail field expose internal hostnames, IP addresses, port numbers, and network topology details.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.Fixed in #25274 (commit 57b11d405):
The fix was backported to all supported release lines:
| Release line | Patched version | |---|---| | 2.33 | v2.33.3 | | 2.32 | v2.32.2 | | 2.31 | v2.31.12 | | 2.30 | v2.30.8 | | 2.29 | v2.29.13 | | 2.24 (ESR) | v2.24.5 |
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.
We'd like to thank Ben Tran of calif.io and Anthropic's Security Team (ANT-2026-22447) for independently disclosing this issue!
{
"github_reviewed": true,
"github_reviewed_at": "2026-05-19T19:53:51Z",
"nvd_published_at": null,
"severity": "MODERATE",
"cwe_ids": [
"CWE-918"
]
}