Skip to content

Rate-limit /registration/resend-email/ and /verify-and-login/ #45

@Dandiggas

Description

@Dandiggas

Problem

The email-verification flow (#16) exposes two unauthenticated endpoints that can be abused to burn SendGrid quota or enumerate accounts:

  • `POST /api/v1/dj-rest-auth/registration/resend-email/` — given an email, sends a fresh verification link. No rate limit. An attacker scripting this against a user's email could exhaust our SendGrid free-tier quota (100/day) or flood the user's inbox.
  • `POST /api/v1/dj-rest-auth/registration/verify-and-login/` — given a key, confirms + issues a token. Keys are HMAC-signed and unguessable, so brute force isn't practical, but adding a basic per-IP limit is defensive hygiene.

Expected behaviour

  • Resend endpoint: limit to ~5 requests per email per hour, ~20 per IP per hour.
  • Verify-and-login endpoint: limit to ~20 requests per IP per minute (looser, since legit users click the link once).
  • Rejected requests return 429 with a clear `Retry-After` header.

Implementation notes

  • `django-ratelimit` is the lightweight option; `django-axes` is heavier but adds auth-attempt tracking.
  • Must work behind Railway's proxy — use `X-Forwarded-For` for IP extraction.
  • Add tests asserting 429 after N requests in a window.

Scope

Follow-up to #16; spec `docs/superpowers/specs/2026-04-20-email-verification-magic-link-design.md` §7 calls this out as out-of-scope for MVP.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions