Skip to content

feat(security): add abuse controls and correlation IDs to mutation routes - #138

Open
woahwhattheheck wants to merge 8 commits into
RemitFlow:mainfrom
woahwhattheheck:wire/rfb-131-abuse-controls
Open

woahwhattheheck wants to merge 8 commits into
RemitFlow:mainfrom
woahwhattheheck:wire/rfb-131-abuse-controls

Conversation

@woahwhattheheck

Copy link
Copy Markdown

Summary

Closes #131.

Adds production-shaped abuse controls on transfer, user, quote, and admin mutation routes, plus sanitized correlation-id propagation so accepted commands can be traced without leaking account secrets.

Note: #133 already has an open solid PR (#137), so this targets the unassigned fallback issue #131 instead of reminting lifecycle concurrency work.

What

  • Bounded in-memory fixed-window rate limiter (maxKeys eviction) used for the global /api budget and for route-family mutation budgets.
  • Per-actor mutation limits after auth for transfer writes, user writes, and admin diagnostics; IP-keyed limit for public GET /api/quote.
  • Actor keys are truncated SHA-256 fingerprints of the API token / admin key — never the raw secret.
  • TRUST_PROXY gates whether X-Forwarded-For can influence client identity (off by default).
  • Correlation ids accept safe inbound X-Request-Id / X-Correlation-Id, reject unsafe values, and echo on both response headers and error envelopes.
  • Documented defaults and env knobs in docs/ABUSE_CONTROLS.md.

Why

High-volume retries and automated abuse can exhaust provider quotas and make incidents hard to correlate. Route-specific actor limits bound bursts; sanitized correlation ids keep every accepted command traceable without putting tokens or account data into logs or headers.

How tested

  • npm test — 267 passing (includes new test/abuseControls.test.js).
  • New coverage: burst → 429 + Retry-After, actor isolation, proxy-trust forgery rejection, distinct forwarded IPs when trusted, maxKeys bound under identity flood, correlation echo on success/429 without token leakage, unsafe inbound correlation replacement.

Design tradeoffs

  • In-process maps (same store boundary as the rest of the demo backend). A multi-instance deploy should swap in Redis/CAS; the HTTP contract (429, rate-limit headers, correlation headers) stays the same.
  • Limiters are no-ops under NODE_ENV=test unless forceInTest / ENABLE_RATE_LIMIT_IN_TEST=1, so the functional suite stays independent of the abuse budget while dedicated regressions still run.

…utes

Bound transfer, user, quote, and admin mutation traffic with per-actor
fixed-window limits, bounded limiter state, and safe 429 responses.
Sanitize and propagate X-Request-Id / X-Correlation-Id without echoing
secrets. Closes RemitFlow#131.
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.

security(backend): add abuse controls and correlation IDs to mutation routes

1 participant