Ameer Mousavi
Ameer Mousavi

Reputation: 1363

Protecting express js server from brute force

I'm writing an api using nodejs and express and my app is hosted by openshift free plan. I want to protect my routes from brute force. For example if an IP sends more than 5 requests /sec then block it for 5 minutes. :)

Upvotes: 1

Views: 7384

Answers (3)

Animir
Animir

Reputation: 1204

It is better to limit rates on reverse-proxy, load balancer or any other entry point to your node.js app.

However, it doesn't fit requirements sometimes.

rate-limiter-flexible package has block option you need

const { RateLimiterMemory } = require('rate-limiter-flexible');

const opts = {
  points: 5, // 5 points
  duration: 1, // Per second
  blockDuration: 300, // block for 5 minutes if more than points consumed 
};

const rateLimiter = new RateLimiterMemory(opts);

const rateLimiterMiddleware = (req, res, next) => {
  // Consume 1 point for each request
  rateLimiter.consume(req.connection.remoteAddress)
    .then(() => {
      next();
    })
    .catch((rejRes) => {
      res.status(429).send('Too Many Requests');
    });
};

app.use(rateLimiterMiddleware);

You can configure rate-limiter-flexible for any exact route. See official express docs about using middlwares

There are also options for Cluster or distributed apps and many others useful

Upvotes: 5

jzacharuk
jzacharuk

Reputation: 2116

There are several packages on NPM that are dedicated to this, if you are using the Express framework:

These can be used for limiting by ip, but also by other information (e.g. by username for failed login attempts).

Upvotes: 5

Trott
Trott

Reputation: 70075

There's nothing stopping you from implementing this in Node.js/express directly, but this sort of thing is typically (and almost certainly more easily) handled by using something like nginx or Apache httpd to handle traffic to your app.

This has the added benefit of allowing you to run the app entirely as an unprivileged user because nginx (or whatever) will be binding to ports 80 and 443 (which requires administrative/superuser/whatever privileges) rather than your app. Plus you can easily get a bunch of other desirable features, like caching for static contents.

nginx has a module specifically for this:

The ngx_http_limit_req_module module (0.7.21) is used to limit the request processing rate per a defined key, in particular, the processing rate of requests coming from a single IP address.

Upvotes: 10

Related Questions