From 66ebe82498fcad8da70ec52ebb36e5bc27a838be Mon Sep 17 00:00:00 2001 From: anshul23102 Date: Tue, 2 Jun 2026 16:30:43 +0530 Subject: [PATCH] fix(auth): apply authLimiter to OTP and password-reset endpoints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit send-otp, verify-otp, forgot-password, and reset-password fell under router.use(dashboardLimiter) — 1000 requests per 15 minutes — because they were defined after that middleware call. authLimiter (10 req/15 min) was only applied to /login and /register. An attacker could: - Brute-force POST /verify-otp at 1000 attempts per 15 minutes - Flood POST /send-otp to exhaust OTP email budget - Iterate POST /forgot-password to enumerate registered accounts Fix: move the four endpoints before router.use(dashboardLimiter) and apply authLimiter explicitly to each. They are now capped at 10 requests per 15 minutes per IP, matching the login and register endpoints. Closes #246 --- apps/dashboard-api/src/routes/auth.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/apps/dashboard-api/src/routes/auth.js b/apps/dashboard-api/src/routes/auth.js index 3ef3aa512..7f588b20f 100644 --- a/apps/dashboard-api/src/routes/auth.js +++ b/apps/dashboard-api/src/routes/auth.js @@ -34,18 +34,20 @@ router.post('/login', authLimiter, login); router.get('/github/start', startGithubAuth); router.get('/github/callback', handleGithubCallback); +// OTP and password-reset routes must use authLimiter (10 req/15 min) because +// they are credential-adjacent endpoints. Placing them before router.use(dashboardLimiter) +// ensures only authLimiter applies; they never fall through to the 1000 req/15 min bucket. +router.post('/send-otp', authLimiter, sendOtp); +router.post('/verify-otp', authLimiter, verifyOtp); +router.post('/forgot-password', authLimiter, forgotPassword); +router.post('/reset-password', authLimiter, resetPassword); + router.use(dashboardLimiter); router.put('/change-password', authorization, changePassword); router.delete('/delete-account', authorization, deleteAccount); -router.post('/send-otp', sendOtp); -router.post('/verify-otp', verifyOtp); - -router.post('/forgot-password', forgotPassword); -router.post('/reset-password', resetPassword); - router.post('/refresh-token', refreshToken); router.post('/logout', authorization, logout);