Skip to content

ExpressBrute migration

Roman edited this page Apr 8, 2019 · 23 revisions

rate-limiter-flexible package provides options and API compatible middleware ExpressBruteFlexible, which makes it easy to migrate from non-maintained and vulnerable to race conditions ExpressBrute package.

ExpressBruteFlexible implements the same logic, but with atomic increments. Note, it works slower on high traffic, as atomic increments cost some performance on store level.

const ExpressBruteFlexible = require('rate-limiter-flexible/lib/ExpressBruteFlexible');
const redis = require('redis');
const http = require('http');
const express = require('express');

const redisClient = redis.createClient({
  enable_offline_queue: false,
});

const opts = {
  freeRetries: 10,
  minWait: 1000,
  maxWait: 10000,
  lifetime: 30,
  storeClient: redisClient,
};

const bruteforce = new ExpressBruteFlexible(ExpressBruteFlexible.LIMITER_TYPES.REDIS, opts);

const app = express();

app.post('/auth',
	bruteforce.prevent, // error 429 if we hit this route too often
	function (req, res, next) {
		res.send('Success!');
	}
);

ExpressBruteFlexible constructor requires to set a limiter type one from ExpressBruteFlexible.LIMITER_TYPES.*. The second argument is options.

Options are the same except:

  1. storeClient should be added in case of using any limiter type except MEMORY and CLUSTER.
  2. dbName may be set if necessary. It depends on limiter type.
  3. tableName may be set if all limits data should be stored in one table.
  4. storeType should be set to 'knex', if it is used.

Other notes:

  1. ExpressBruteFlexible always works with refreshTimeoutOnRequest=false option.
  2. it works only with seconds since rate-limiter-flexible duration is in seconds. For example, if minWait=500 it is 1 second.