From 6a520f5b26a3e2ed6345721b30ff4e3d9bfa903d Mon Sep 17 00:00:00 2001 From: Sabir Hassan Date: Thu, 27 Apr 2023 15:06:24 +0500 Subject: [PATCH] fix: use RateLimiterMemory instead of RateLimiterMongo --- README.md | 2 +- api/src/utils/rateLimiter.ts | 21 +++++++++------------ 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index a6a9e6a..64a210b 100644 --- a/README.md +++ b/README.md @@ -184,7 +184,7 @@ MAX_WRONG_ATTEMPTS_BY_IP_PER_DAY = default: 100; # After this, access is blocked for an hour -# Store number for 90 days since first fail +# Store number for 24 days since first fail # Once a successful login is attempted, it resets MAX_CONSECUTIVE_FAILS_BY_USERNAME_AND_IP = default: 10; diff --git a/api/src/utils/rateLimiter.ts b/api/src/utils/rateLimiter.ts index d8b3cb0..a6ec1b0 100644 --- a/api/src/utils/rateLimiter.ts +++ b/api/src/utils/rateLimiter.ts @@ -1,10 +1,9 @@ -import mongoose from 'mongoose' -import { RateLimiterMongo } from 'rate-limiter-flexible' +import { RateLimiterMemory } from 'rate-limiter-flexible' export class RateLimiter { private static instance: RateLimiter - private limiterSlowBruteByIP: RateLimiterMongo - private limiterConsecutiveFailsByUsernameAndIP: RateLimiterMongo + private limiterSlowBruteByIP: RateLimiterMemory + private limiterConsecutiveFailsByUsernameAndIP: RateLimiterMemory private maxWrongAttemptsByIpPerDay: number private maxConsecutiveFailsByUsernameAndIp: number @@ -19,19 +18,17 @@ export class RateLimiter { MAX_CONSECUTIVE_FAILS_BY_USERNAME_AND_IP ) - this.limiterSlowBruteByIP = new RateLimiterMongo({ - storeClient: mongoose.connection, + this.limiterSlowBruteByIP = new RateLimiterMemory({ keyPrefix: 'login_fail_ip_per_day', points: this.maxWrongAttemptsByIpPerDay, duration: 60 * 60 * 24, blockDuration: 60 * 60 * 24 // Block for 1 day }) - this.limiterConsecutiveFailsByUsernameAndIP = new RateLimiterMongo({ - storeClient: mongoose.connection, + this.limiterConsecutiveFailsByUsernameAndIP = new RateLimiterMemory({ keyPrefix: 'login_fail_consecutive_username_and_ip', points: this.maxConsecutiveFailsByUsernameAndIp, - duration: 60 * 60 * 24 * 90, // Store number for 90 days since first fail + duration: 60 * 60 * 24 * 24, // Store number for 24 days since first fail blockDuration: 60 * 60 // Block for 1 hour }) } @@ -60,8 +57,7 @@ export class RateLimiter { this.limiterConsecutiveFailsByUsernameAndIP.get(usernameIPkey) ]) - // NOTE: To make use of blockDuration option from RateLimiterMongo - // comparison in both following if statements should have greater than symbol + // NOTE: To make use of blockDuration option, comparison in both following if statements should have greater than symbol // otherwise, blockDuration option will not work // For more info see: https://github.com/animir/node-rate-limiter-flexible/wiki/Options#blockduration @@ -103,10 +99,11 @@ export class RateLimiter { if (rlRejected instanceof Error) { throw rlRejected } else { - // based upon the implementation of consume method of RateLimiterMongo + // based upon the implementation of consume method of RateLimiterMemory // we are sure that rlRejected will contain msBeforeNext // for further reference, // see https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#login-endpoint-protection + // or see https://github.com/animir/node-rate-limiter-flexible#ratelimiterres-object return Math.ceil(rlRejected.msBeforeNext / 1000) } }