Skip to content

hotfix(auth): block disposable email domains on signup#1414

Merged
joelorzet merged 1 commit into
stagingfrom
hotfix/block-disposable-email-signups
May 29, 2026
Merged

hotfix(auth): block disposable email domains on signup#1414
joelorzet merged 1 commit into
stagingfrom
hotfix/block-disposable-email-signups

Conversation

@joelorzet
Copy link
Copy Markdown

Summary

  • Adds a databaseHooks.user.create.before hook in lib/auth.ts that rejects sign-ups from disposable / temporary email domains. Both email+password and OAuth (Google / GitHub) flow through user.create, so a single hook closes both paths.
  • Curated headline set covers the publicly-known throwaway services: Mailinator, YOPmail, Guerrilla Mail / sharklasers / grr.la, 10MinuteMail, Maildrop, EmailOnDeck, DisposableMail, Temp-Mail, Mailnesia, GetNada, Throwawaymail, Trashmail, Dispostable, Fakemail, plus aliasing services (SimpleLogin, addy.io, Firefox Relay, DuckDuckGo, Burner Mail, IronVest).
  • Maintained fallback list vendored as lib/auth-disposable-email-domains.json (5,488 domains, from disposable-email-domains/disposable-email-domains). Lookup is O(1) via a Set.
  • isDisposableEmailDomain handles case folding, +alias local-parts, multi-@ inputs, whitespace around the domain, and exact-domain match only (no substring collisions).

Files

  • lib/auth-disposable-emails.ts -- the lookup module (curated set + bundled fallback)
  • lib/auth-disposable-email-domains.json -- 5,488-domain vendored fallback list
  • lib/auth.ts -- databaseHooks.user.create.before rejects when isDisposableEmailDomain(email) returns true
  • tests/unit/auth-disposable-emails.test.ts -- 13 unit tests covering the headline set, casing, +alias, malformed inputs, and substring non-collision

Rejects sign-ups from disposable / temporary email providers on both the
email+password path and OAuth (Google / GitHub) callbacks. Both paths
flow through better-auth's databaseHooks.user.create, so a single
before-hook in lib/auth.ts catches them.

The blocklist combines a curated headline set (Mailinator, YOPmail,
Guerrilla Mail, 10MinuteMail, Maildrop, EmailOnDeck, DisposableMail,
Temp-Mail, Mailnesia, GetNada, Throwawaymail, Trashmail, Dispostable,
Fakemail, plus aliasing services SimpleLogin, addy.io, Firefox Relay,
DuckDuckGo, Burner Mail, IronVest) with the maintained
disposable-email-domains.json fallback (5,488 domains, vendored from the
disposable-email-domains/disposable-email-domains repo).

isDisposableEmailDomain handles case folding, +alias local-parts, and
multi-@ inputs via lastIndexOf. Exact-domain match only -- substring
collisions like 'notmailinator.com' are intentionally checked against
the full vendored list to avoid false positives or negatives.
@joelorzet joelorzet merged commit 89aa692 into staging May 29, 2026
31 checks passed
@joelorzet joelorzet deleted the hotfix/block-disposable-email-signups branch May 29, 2026 21:13
@github-actions
Copy link
Copy Markdown

🧹 PR Environment Cleaned Up

The PR environment has been successfully deleted.

Deleted Resources:

  • Namespace: pr-1414
  • All Helm releases (Keeperhub, Scheduler, Event services)
  • PostgreSQL Database (including data)
  • LocalStack, Redis
  • All associated secrets and configs

All resources have been cleaned up and will no longer incur costs.

@github-actions
Copy link
Copy Markdown

ℹ️ No PR Environment to Clean Up

No PR environment was found for this PR. This is expected if:

  • The PR never had the deploy-pr-environment label
  • The environment was already cleaned up
  • The deployment never completed successfully

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