Rate-limit POST /admin/login to bound bcrypt-induced event-loop stalls
Async bcryptjs measured to still not yield the event loop for realistic
hash costs (~70ms compares finish before its 100ms yield threshold), so
a login flood could still stall the same process's live MegaPay payment
webhooks. Caps each client (or shared-proxy-bucket, see known limitation
below) to 5 POST /admin/login attempts per rolling 60s window via
express-rate-limit; requests over the limit get a 429 with a Vietnamese
error and never reach adminAuth.login, so the bcrypt compare never runs.
Known limitation: this app has no app.set('trust proxy', ...) configured
and runs behind a reverse proxy in production, so express-rate-limit's
default req.ip-based bucketing will key off the proxy's address, not the
real client IP. In production this enforces "5 attempts/minute in
aggregate behind the proxy" rather than "5 per real client IP" — an
accepted trade-off for this low-traffic internal tool, but not the same
guarantee trust proxy + per-IP limiting would give. Configuring trust
proxy is an infrastructure change, left out of scope here.
Showing
app/middlewares/loginRateLimit.js
0 → 100644
| ... | ... | @@ -29,6 +29,7 @@ |
| "dateformat": "^3.0.3", | ||
| "dotenv": "^17.4.2", | ||
| "express": "^4.14.0", | ||
| "express-rate-limit": "^6.11.2", | ||
| "express-session": "^1.13.0", | ||
| "glob": "^7.2.3", | ||
| "he": "^0.5.0", | ||
| ... | ... |
Please
register
or
sign in
to comment