Skip to content

fix(security): per-IP rate limiting on login and ingest - #48

Merged
ClaraVnk merged 1 commit into
mainfrom
feat/sec-rate-limit
Jun 30, 2026
Merged

fix(security): per-IP rate limiting on login and ingest#48
ClaraVnk merged 1 commit into
mainfrom
feat/sec-rate-limit

Conversation

@ClaraVnk

Copy link
Copy Markdown
Contributor

Pentest remediation β€” finding #3 (no rate limiting).

  • In-memory sliding-window limiter (no new dep) caps POSTs per IP: login (/api/auth/ login + /login, default 10/min) and /api/ingest (default 600/min). 0 disables;
    over-limit β†’ 429 + Retry-After. Configurable via RATE_LIMIT_*.
  • Per-process; documented to also rate-limit at the proxy behind a load balancer.

Tests: sliding-window logic + 11th login β†’ 429. Full suite 230 passed; ruff +
mypy(strict) green.

Address the pentest finding that authentication and ingestion had no rate limiting
(brute-force / credential-stuffing / flood).

- A small in-memory sliding-window limiter (no new dependency) caps POSTs per IP:
  `/api/auth/login` + `/login` at `RATE_LIMIT_LOGIN_PER_MINUTE` (default 10/min) and
  `/api/ingest` at `RATE_LIMIT_INGEST_PER_MINUTE` (default 600/min). 0 disables.
  Over-limit returns 429 with `Retry-After`. Argon2's per-attempt cost already slows
  guessing; this stops the volume.
- The limiter is created per app instance and is per-process β€” documented as needing
  proxy-level limiting behind a load balancer (multi-instance state is out of scope).

Tests: the sliding-window allow/deny logic, and an 11th login in the window β†’ 429.
Full suite 230 passed; ruff + mypy(strict) green.
@ClaraVnk
ClaraVnk merged commit a7b461d into main Jun 30, 2026
4 checks passed
@ClaraVnk
ClaraVnk deleted the feat/sec-rate-limit branch June 30, 2026 21:27
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