Skip to content

fix!: reject OIDC login when email_verified claim is non-bool or absent (#25713)#26177

Open
jdomeracki-coder wants to merge 1 commit into
release/2.34from
cherry-pick/25713/release/2.34
Open

fix!: reject OIDC login when email_verified claim is non-bool or absent (#25713)#26177
jdomeracki-coder wants to merge 1 commit into
release/2.34from
cherry-pick/25713/release/2.34

Conversation

@jdomeracki-coder

@jdomeracki-coder jdomeracki-coder commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Backport of #25713 to release/2.34.

Cherry-picked with git cherry-pick -x (d5b0e93c6c); the commit body references the original PR.

Generated by Coder Agents on behalf of @jdomeracki-coder.

…nt (#25713)

## Problem

The OIDC callback checks `email_verified` via a Go type assertion
(`verifiedRaw.(bool)`). When an IdP returns the claim as a string
(`"false"`), a number, or omits it entirely, the assertion fails
silently and the email is implicitly treated as verified. Several real
IdPs (SAML-to-OIDC bridges, certain Azure AD B2C configurations) emit
string-typed booleans, making this reachable in practice.

## Fix

Add `coerceEmailVerified()` to handle `bool`, `string`
(`"true"`/`"false"`/`"1"`/`"0"` via `strconv.ParseBool`), `float64`,
`json.Number`, and `int`/`int64` variants. Rewrite the check to be
fail-closed: an absent claim, an unrecognized type, or any non-truthy
value is treated as unverified and rejected. The existing
`IgnoreEmailVerified` config option remains as an escape hatch.

Fixes https://linear.app/codercom/issue/PLAT-228

> Generated with [Coder Agents](https://coder.com) by @f0ssel

<details><summary>Implementation plan</summary>

### Production code (`coderd/userauth.go`)
- Added `encoding/json` import
- Added `coerceEmailVerified(v interface{}) (verified bool, ok bool)`
helper near EOF
- Replaced the type-assertion block (lines ~1342-1363) with fail-closed
logic that uses `coerceEmailVerified`

### Unit tests (`coderd/userauth_internal_test.go`, new file)
- Table-driven test covering: `bool`, `string` (`"true"`, `"false"`,
`"1"`, `"0"`, `"TRUE"`, `"t"`, `"f"`, `"invalid"`, `""`), `json.Number`,
`float64`, `int`, `int64`, `nil`, `[]string{}`, `map[string]string{}`

### Integration tests (`coderd/userauth_test.go`,
`coderd/users_test.go`)
- Added 3 new test cases: `EmailVerifiedMissingIgnored` (200),
`EmailVerifiedAsStringTrue` (200), `EmailVerifiedAsStringFalse` (403)
- Updated existing test cases that omitted `email_verified` and expected
success to include `"email_verified": true`

### FakeIDP (`coderd/coderdtest/oidctest/idp.go`)
- `encodeClaims` now defaults `email_verified` to `true` (like `exp`,
`aud`, `iss`) so tests that don't care about the verification flow are
unaffected
</details>

(cherry picked from commit d5b0e93)
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown

👋 Hey @jdomeracki-coder!

This PR is targeting the release/2.34 release branch, but its title does not start with fix: or fix(scope):.

Only bug fixes should be cherry-picked to release branches. If this is a bug fix, please update the PR title to match the conventional commit format:

fix: description of the bug fix
fix(scope): description of the bug fix

If this is not a bug fix, it likely should not target a release branch.

@coder-tasks

coder-tasks Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Documentation Check

Updates Needed

  • docs/admin/users/oidc-auth/index.md - Lines 55-58 currently state: "If the email_verified claim is present in the token response from the identity provider, Coder will validate that its value is true." This implies a missing claim is acceptable. After this PR, a missing email_verified claim also causes login rejection (fail-closed). The docs must be updated to reflect:
    1. The email_verified claim is now required (absence causes rejection).
    2. Non-boolean representations (string "true"/"false", numeric 1/0) are coerced, but unrecognized types are treated as unverified.
    3. CODER_OIDC_IGNORE_EMAIL_VERIFIED=true bypasses both missing-claim and false-value rejection.

Automated review via Coder Agents

@jdomeracki-coder jdomeracki-coder requested a review from f0ssel June 9, 2026 19:00

@f0ssel f0ssel left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Backport of #25713 to release/2.34.

Verified as a clean version backport: identical changed files and diff stats to the sibling backports of this fix on the other release branches, with no unrelated files touched. Approving as requested.

This review was generated by Coder Agents.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants