mars
MARS-395
internal send-email in-memory rate limiter inert under Fluid-OFF (DB-back it)
Done low
cmcoder-mars-cc
Codex finding split off from MARS-391. /api/internal/send-email uses in-process Map rateLimit() (30/hr keyed on bearer). Under Fluid-compute OFF each request may hit a cold isolate -> fresh Map -> limit never accrues (effectively no rate limit). MARS-391 shipped the recipient-domain allowlist which bounds abuse to our own operator inbox (pensanta.com), so non-urgent. Fix: DB-back the counter via COUNT over existing appEvents category='email' action='internal-email-attempt' rows in a rolling window (mirror MARS-393 gate-4 identityFloodExceeded). No schema change. File: src/app/api/internal/send-email/route.ts lines 27-41,71-76.
Questions
No questions.
Activity
-
Audit pre-push edge (non-blocking): recipientDomain() uses lastIndexOf('@') on the raw normalized string, so an RFC-5322 name-addr form 'Name <x@pensanta.com>' would parse domain as 'pensanta.com>' and be blocked. No live caller passes that form (all send bare addresses) + it fails CLOSED, so shipped as-is. If the DB-back work touches this file, also parse the addr-spec out of name-addr before domain extraction.
-
Bumped P3→P2: MARS-391 widen replaces the pensanta.com-only hard-lock with a login-gate domain allowlist; gmail/googlemail are open-registration so the domain gate alone doesn't contain a leaked internal key targeting gmail recipients. Rate-limit is now the primary volume-abuse containment for /api/internal/send-email, not a nice-to-have.
-
DB-backed 60/hr global send-volume cap on /api/internal/send-email replaces the Fluid-OFF-inert in-memory Map: rolling COUNT over appEvents action-scoped to internal-email-* (structurally excludes weekly-kpi fan-out), fail-open on COUNT throw (auth+domain contain WHO; reserve-INSERT fail-closed), warn-tier internal-email-rate-limited on 429. Live 2.24.10, PASS:1026294.
bug
6w ago by wi-cli-venus
6w ago
2026-07-03 12:50