fix(auth): OAuth must require a provider-verified email (#7/#9, account takeover)#219
Merged
Merged
Conversation
…nt takeover) GitHub and Google OAuth linked accounts by email WITHOUT confirming the provider had verified that email — an attacker controlling an unverified address equal to a victim's could link into / impersonate the victim. - GitHub (#9): fetchGitHubUser now ALWAYS resolves the address from /user/emails and accepts ONLY a primary+verified entry, ignoring the attacker-settable public /user profile email entirely. findOrCreateUserGitHub refuses to link-by-email or create a new identity when no verified email resolved. - Google (#7): decode email_verified (tokeninfo, string) / verified_email (userinfo v2, bool) onto googleUser.EmailVerified; findOrCreateUserGoogle refuses link-by-email / create unless verified. Existing google_id matches are unaffected. Per product decision 2026-06-02 (require verified email, reject if unverified). Hermetic regression tests added (httptest, no DB): verified-primary wins over public email; unverified → empty/ rejected; Google verified flag flows through. Test harness updated to emit the verified flags. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
DB-backed tests: GitHub login with no primary+verified email and Google login with email_verified=false are both REFUSED (non-200) — exercises the errOAuthEmailUnverified return branches. Closes the #219 patch-coverage gap on auth.go. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- auth_final2 startEmptyNameGoogleOAuth: emit email_verified:"true" so the Google verified-email requirement (#7) is satisfied by the bespoke server. - tier_enforcement IsDedicatedTier: team is now dedicated (#12, via merged common defaultYAML). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
#219 coverage) diff-cover flagged auth.go:1420-1422 (the bug-bash #7 account-takeover guard) uncovered: the existing handler-level test drives the id_token/body flow, but the browser-callback path (GoogleCallbackBrowser → userinfo v2 → findOrCreateUserGoogle) reaches the guard via a code path that test doesn't exercise deterministically. Adds hermetic white-box tests (package handlers, sqlmock — no DB container) that call findOrCreateUserGoogle / findOrCreateUserGitHub directly with an unverified/empty-email new identity and a missing google_id/github_id lookup, asserting errOAuthEmailUnverified. Locks the security guard against regression. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Security (account takeover). GitHub/Google OAuth linked accounts by email without confirming the provider verified it.
/useremail; always resolve from/user/emailsaccepting only primary+verified; refuse link/create without a verified email.email_verified/verified_email→googleUser.EmailVerified; refuse link/create unless verified. Existinggoogle_idmatches unaffected.Per product decision 2026-06-02. Hermetic regression tests added (httptest, no DB). 🤖 Generated with Claude Code