Skip to content

fix: prevent OAuth account pre-hijacking via unverified email linking#503

Merged
lakhansamani merged 1 commit intomainfrom
fix/oauth-account-pre-hijacking
Mar 30, 2026
Merged

fix: prevent OAuth account pre-hijacking via unverified email linking#503
lakhansamani merged 1 commit intomainfrom
fix/oauth-account-pre-hijacking

Conversation

@lakhansamani
Copy link
Copy Markdown
Contributor

Summary

  • Security fix: Prevents account pre-hijacking attack where an attacker pre-registers with a victim's email (without verifying), then gains persistent password access after the victim logs in via OAuth.
  • When an OAuth login matches an existing unverified account, the unverified account is now deleted and a fresh account is created for the OAuth user — the attacker's password is not preserved.
  • When the existing account is verified, behavior is unchanged (OAuth identity is linked normally).
  • Added 6 integration tests covering: unverified account replacement, verified account linking, end-to-end attacker login failure, revoked account handling, multi-provider linking, and clean deletion.

Attack scenario (before fix)

  1. Attacker signs up with victim@company.com + password, does NOT verify email
  2. Victim logs in via Google OAuth (normal behavior)
  3. OAuth callback links Google identity to attacker's account, auto-verifies email
  4. Attacker logs in with their original password — full account takeover

Test plan

  • TestOAuthAccountLinkingPreHijack/unverified_account_should_not_retain_password_after_oauth_signup
  • TestOAuthAccountLinkingPreHijack/verified_account_should_link_oauth_identity
  • TestOAuthAccountLinkingPreHijack/attacker_cannot_login_after_victim_oauth
  • TestOAuthAccountLinkingPreHijack/revoked_unverified_account_should_block_oauth
  • TestOAuthAccountLinkingPreHijack/multiple_oauth_providers_link_to_verified_account
  • TestOAuthAccountLinkingPreHijack/unverified_account_deletion_is_clean

When an OAuth login matches an existing account by email, the handler
now checks EmailVerifiedAt. If the existing account's email was never
verified, the unverified account is deleted and a fresh one is created
for the OAuth user. This prevents attackers from pre-registering with
a victim's email to retain password access after the victim's OAuth login.
@lakhansamani
Copy link
Copy Markdown
Contributor Author

@lakhansamani lakhansamani merged commit 2a9d22f into main Mar 30, 2026
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