Skip to content

fix(auth): refuse account creation from disposable email domains for every provider - #9516

Merged
waleedlatif1 merged 2 commits into
stagingfrom
fix/server-disposable-signup
Oct 31, 2026
Merged

waleedlatif1 merged 2 commits into
stagingfrom
fix/server-disposable-signup

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • Refuse account creation from disposable/temporary email domains on hosted, in databaseHooks.user.create.before, so it covers Google, GitHub, Microsoft, SSO, and email signups alike. Previously the only disposable check was the ~20-domain client-side list in quickValidateEmail, which OAuth signups never hit
  • Vendored list (disposable-email-domains.json, ~98.7k domains) is the union of disposable/disposable-email-domains (MIT) and disposable-email-domains/disposable-email-domains (CC0) at pinned commits — no new package dependency, the reviewed diff is what ships
  • Matches the domain and its parents (x.mailinator.com), lazy-loaded on first account creation so no other module pays the parse at startup; fails open (logs, allows signup) if the list can't load, and a failed load is retried rather than cached
  • Only new accounts are affected: sign-in, existing accounts, and the AppConfig block lists are unchanged; self-hosted (!isHosted) is unchanged
  • Refused OAuth signups land on /oauth-error with a clear message (use a permanent email address) instead of the generic "try again" — mapped for both Better Auth 1.6 (message slug) and 1.7 (error code) redirect shapes

Type of Change

  • Bug fix

Testing

  • Sanity run of isDisposableEmail under Bun: disposable domains, subdomains, and mixed case refused; Gmail, Outlook, iCloud, Proton, DuckDuckGo/Firefox Relay, corporate and .edu domains, example.test, and missing/empty emails allowed; 1,000 checks in 0.5ms after the first load
  • Checked the list contains no mainstream provider, mail relay, TLD, or public suffix, and none of the domains used by E2E/integration signup fixtures
  • Read Better Auth 1.6.27 and 1.7.12 OAuth callback paths to confirm how a user.create.before APIError is redirected
  • Biome on changed files; type-check, check:audits, and test suites in CI

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing (new tests pass the test-audit authoring gate)
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel

vercel Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
docs Skipped Skipped Oct 31, 2026 8:38am UTC

Request Review

@greptile-apps

greptile-apps Bot commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no new blocking issue was found.

Summary

The PR blocks disposable email domains when hosted accounts are created, across sign-up providers.

  • Hosted signups now block disposable email domains across providers.

Reviews (2) · Last reviewed commit: "fix(auth): keep permanent mail-relay ali..." · Reviewed by Greptile

@greptile-apps

greptile-apps Bot commented Oct 31, 2026

Copy link
Copy Markdown
Contributor

Comments Outside Diff

These findings could not be posted inline.

  • P1 Permanent aliases cannot sign up apps/sim/lib/messaging/email/disposable-email-domains.json:5607 ▶

    addy.to is an addy.io forwarding domain, not a temporary inbox provider. Including it here makes isDisposableEmail reject permanent aliases at that domain, so their owners cannot create hosted accounts through email or OAuth. This conflicts with the checker's stated intent to preserve mail relays. Remove this entry and exclude permanent relay domains when refreshing the list.

    
    

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 5 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Turn on auto-fix | Re-trigger cubic

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

Re: permanent aliases (addy.to) — fixed in dcee401. Relay services are now exempted in code (MAIL_RELAY_DOMAINS in disposable.ts: addy.io/anonaddy, SimpleLogin, Proton Pass, Firefox Relay, DuckDuckGo, iCloud Hide My Email, 33mail, Mask My ID, Abine), checked against the domain and every parent, before the list lookup. This also covers per-alias upstream entries like <alias>.mozmail.com and <alias>.anonaddy.com. The vendored JSON stays an exact union of upstream so a refresh can't reintroduce them.

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 31, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@waleedlatif1 I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 5 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Turn on auto-fix | Re-trigger cubic

This branch was previously deployed

1 inactive deployment
Preview — dcee4016 Deployed Oct 31, 2026 by vercel[bot]
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