Preventing Brute Force Using Node and Express JS Preventing Brute Force Using Node and Express JS express express

Preventing Brute Force Using Node and Express JS


So after doing some searching, I wasn't able to find a solution I liked so I wrote my own based on Trevor's solution and express-brute. You can find it here.


Maybe something like this might help you get started.

var failures = {};function tryToLogin() {    var f = failures[remoteIp];    if (f && Date.now() < f.nextTry) {        // Throttled. Can't try yet.        return res.error();    }    // Otherwise do login    ...}function onLoginFail() {    var f = failures[remoteIp] = failures[remoteIp] || {count: 0, nextTry: new Date()};    ++f.count;    f.nextTry.setTime(Date.now() + 2000 * f.count); // Wait another two seconds for every failed attempt}function onLoginSuccess() { delete failures[remoteIp]; }// Clean up people that have given upvar MINS10 = 600000, MINS30 = 3 * MINS10;setInterval(function() {    for (var ip in failures) {        if (Date.now() - failures[ip].nextTry > MINS10) {            delete failures[ip];        }    }}, MINS30);


rate-limiter-flexible package with Redis or Mongo for distributed apps and in-Memory or with Cluster helps

Here is example with Redis

const { RateLimiterRedis } = require('rate-limiter-flexible');const Redis = require('ioredis');const redisClient = new Redis({  options: {    enableOfflineQueue: false  }});const opts = {  redis: redisClient,  points: 5, // 5 points  duration: 15 * 60, // Per 15 minutes  blockDuration: 15 * 60, // block for 15 minutes if more than points consumed };const rateLimiter = new RateLimiterRedis(opts);app.post('/auth', (req, res, next) => {  const loggedIn = loginUser();  if (!loggedIn) {      // Consume 1 point for each failed login attempt      rateLimiter.consume(req.connection.remoteAddress)        .then((data) => {          // Message to user          res.status(400).send(data.remainingPoints + ' attempts left');        })        .catch((rejRes) => {          // Blocked          const secBeforeNext = Math.ceil(rejRes.msBeforeNext / 1000) || 1;          res.set('Retry-After', String(secBeforeNext));          res.status(429).send('Too Many Requests');        });  } else {    // successful login  }});