Skip to content

Block sign-ups from disposable email domains #2237

Description

@nicolai-rhesis

Summary

Block self-serve sign-ups (email/password, magic link, OAuth) that use disposable / trash email domains, using a maintained community list plus a small custom list for domains we observe on Rhesis that aren't upstream yet.

Problem / Opportunity

Disposable-email domains are used to create throwaway accounts that spam or abuse the platform. We currently only validate email format + MX deliverability, so temporary inboxes (mailinator.com, 10minutemail.com, etc.) pass. We've also seen recent sign-ups from trash domains not yet covered by public lists.

Users & Use Cases

  • Persona: Rhesis platform / operations.
  • Use case: Prevent abusive throwaway sign-ups while letting legitimate users register.

Proposal

  1. Source list: disposable-email-domains PyPI package (MIT, exposes blocklist as a set, ~daily updates). Library repo: https://github.com/disposable-email-domains/python-disposable-email-domains (packaged form of https://github.com/disposable-email-domains/disposable-email-domains). Add via uv add disposable-email-domains in apps/backend.

  2. Custom list in repo: app/auth/disposable_domains_custom.txt, loaded with Path(__file__).parent (same pattern as bulk_defaults.json) and merged with the PyPI set. This is where we add domains the public list is missing.

  3. Optional env override AUTH_DISPOSABLE_EMAIL_EXTRA_DOMAINS (comma-separated) for blocking a domain urgently without a deploy.

  4. Toggle AUTH_BLOCK_DISPOSABLE_EMAILS (default true) on AuthSettings.

  5. Enforcement: extend validate_and_normalize_email() with reject_disposable (progressive subdomain stripping), applied to self-serve sign-up paths only:

    • EmailProvider.register()
    • request_magic_link() (currently bypasses domain validation)
    • OAuth new-user branch in find_or_create_user_from_auth()

    Admin invites (POST /users/) are NOT blocked.

Non-Goals / Out of Scope

  • No blocking of existing users or admin-invited users.
  • No UI for managing the list in this iteration (repo file + env override only).

Acceptance Criteria (testable)

  • Sign-up with a known disposable domain (e.g. mailinator.com) is rejected with a clear 400 across email/password, magic link, and OAuth first login.
  • Custom-list and env-override domains are also rejected.
  • Legitimate domains and admin invites are unaffected.
  • AUTH_BLOCK_DISPOSABLE_EMAILS=false fully disables the check.

Additional Context

Discussion: keep the list in the repo / use a library rather than a hardcoded env var.
Reviewer: @akwasigroch (proposed the library/repo-list approach).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions