Skip to content

fix(auth): OAuth must require a provider-verified email (#7/#9, account takeover)#219

Merged
mastermanas805 merged 4 commits into
masterfrom
fix/bugbash-api-batch2-2026-06-02
Jun 2, 2026
Merged

fix(auth): OAuth must require a provider-verified email (#7/#9, account takeover)#219
mastermanas805 merged 4 commits into
masterfrom
fix/bugbash-api-batch2-2026-06-02

Conversation

@mastermanas805

Copy link
Copy Markdown
Member

Security (account takeover). GitHub/Google OAuth linked accounts by email without confirming the provider verified it.

Per product decision 2026-06-02. Hermetic regression tests added (httptest, no DB). 🤖 Generated with Claude Code

…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>
@mastermanas805 mastermanas805 enabled auto-merge (squash) June 2, 2026 17:51
mastermanas805 and others added 3 commits June 2, 2026 23:42
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>
@mastermanas805 mastermanas805 merged commit 5ab7371 into master Jun 2, 2026
17 of 18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant