loopback login rate limit

Problem: limit number of login for one user.

Usually user will login with this api

POST /api/users/login
{"email": "foo@bar.baz", "password":"what is a password"}

Statement: Given this user, how could I limit login number n within i interval.

There is a great module from https://github.com/chriso/redback, that provide rate limit https://gist.github.com/chriso/54dd46b03155fcf555adccea822193da. We can use this idea to limit number of login for one user

{ratelimit/login.js}
const redis = require('redis').createClient(REDIS_URL)
const redback = require('redback').use(redis)

let ratelimit = redback.createRateLimit('login')

module.exports = function (req, res, next) {
  const loginRetryInterval = 60 * 5   // 5 mins
  const loginRetryMax = 5             // 5 times

  const key = `body.email:${req.body.email}`
  ratelimit.add(key)

  // count the number of requests in the last 20 seconds
  ratelimit.count(key, loginRetryInterval, (err, requests) => {
    if (err) { return next() }

    if (requests >= loginRetryMax) {
      return res.type('json').status(429).end()
    }

    return next()
  })
}

I will use redis instead of local memory because the program may run in multiple workers.

For loopback, I may use this before loopback itself middleware. At server.js

app.use('/api/users/login', require('./ratelimit/login'))

Using email address as only key to measure attack is so naive, since the true owner of the account cannot login because someone was trying to guess the password? I should include source IP address into the key.

...
const key = `connection.remoteAddress:${req.connection.remoteAddress}:body.email:${req.body.email}`
ratelimit.add(key)
...

With this define, redis will have key like "login:connection.remoteAddress:::ffff:127.0.0.1:body.email:foo@bar.baz".

Cheer.

Trả lời

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Đăng xuất / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Đăng xuất / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Đăng xuất / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Đăng xuất / Thay đổi )

Connecting to %s