Preventing Brute Force Using Node and Express JS Preventing Brute Force Using Node and Express JS node.js node.js

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) => {  // Consume 1 point for each login attempt  rateLimiter.consume(req.connection.remoteAddress)    .then((data) => {      const loggedIn = loginUser();      if (!loggedIn) {        // Message to user        res.status(400).send(data.remainingPoints + ' attempts left');      } else {        // successful login      }    })    .catch((rejRes) => {      // Blocked      const secBeforeNext = Math.ceil(rejRes.msBeforeNext / 1000) || 1;      res.set('Retry-After', String(secBeforeNext));      res.status(429).send('Too Many Requests');    });});