GHSA-686c-7vgv-v3fx is a medium-severity (CVSS 6.5) Server-Side Request Forgery (SSRF) vulnerability in github.com/coder/coder/v2. O3 Security confirms whether GHSA-686c-7vgv-v3fx is actually reachable in your code before you act, and blocks exploitation at runtime until you patch.
Coder: Unauthenticated SSRF via Azure Instance Identity Endpoint
Exploitation Status
No confirmed exploitation observed yet
- CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.
- CISA’s own triage has not observed active exploitation or public proof-of-concept code for this CVE as of its last assessment.
Exploitation and automatability from CISA’s SSVC triage for GHSA-686c-7vgv-v3fx.
EPSS Exploitation Probability
EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.
How urgent is this, really
GHSA-686c-7vgv-v3fx plotted by exploitation likelihood (EPSS) against impact (CVSS). The shaded corner — EPSS 50%+ and CVSS 7.0+ — is where this CVE doesn't sit, though severity or exploitability alone can still warrant action.
Where this sits among everything scored
Of 360,399 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Real counts from FIRST.org, not a sample — log-scaled since the landscape is heavily right-skewed.
Real-World Exposure
github.com/coder/coder/v2🐹github.com/coder/coder/v2🐹github.com/coder/coder/v2🐹github.com/coder/coder/v2🐹github.com/coder/coder/v2🐹github.com/coder/coder/v2🐹github.com/coder/coderReal-time download stats are indexed for npm and PyPI packages. This vulnerability affects Go packages — download data is not available via public APIs for these ecosystems.
Description
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:
- No allowlist on
IssuingCertificateURLhosts. Any URL was accepted. http.DefaultClientwas used. It follows redirects and connects to private, link-local, and loopback addresses.- Unbounded
io.ReadAllon the response body (memory exhaustion vector). - 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
Detailfield expose internal hostnames, IP addresses, port numbers, and network topology details. - Memory exhaustion. The unbounded
io.ReadAllon the response body allows an attacker to pointIssuingCertificateURLat 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 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 |
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!
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 🐹Go | github.com/coder/coder/v2 | ≥ 2.33.0-rc.0&&< 2.33.3 | 2.33.3 |
| 🐹Go | github.com/coder/coder/v2 | ≥ 2.32.0-rc.0&&< 2.32.2 | 2.32.2 |
| 🐹Go | github.com/coder/coder/v2 | ≥ 2.31.0&&< 2.31.12 | 2.31.12 |
| 🐹Go | github.com/coder/coder/v2 | ≥ 2.30.0&&< 2.30.8 | 2.30.8 |
| 🐹Go | github.com/coder/coder/v2 | ≥ 2.29.0&&< 2.29.13 | 2.29.13 |
| 🐹Go | github.com/coder/coder/v2 | all versions | 2.24.5 |
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for github.com/coder/coder/v2. O3's reachability analysis confirms whether the vulnerable code path is actually invoked in your application, so you act on real exposure instead of every transitive match.
Fix
Update github.com/coder/coder/v2 to 2.33.3 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-686c-7vgv-v3fx is resolved across your whole dependency graph.
Workarounds
If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.
How O3 protects you
O3 pinpoints whether GHSA-686c-7vgv-v3fx is reachable in your code and exactly where to fix it, then blocks exploitation in production at runtime until the patched version is deployed.
Tailored to GHSA-686c-7vgv-v3fx. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.
Frequently Asked Questions
Is GHSA-686c-7vgv-v3fx in your dependencies?
O3 detects GHSA-686c-7vgv-v3fx across Go dependencies and uses function-level reachability to confirm whether the vulnerable code path is actually reachable — not just present. No false positives.