How to protect against distributed denial-of-service attacks in Node.js with Socket.io?

Viewed 34856

I have been learning node.js and socket.io lately. My question is how can I protect server against client side attacks?

This is my server code

io.sockets.on('connection', function (socket) { 
//users.push(socket);       
socket.on('message', function (data) {      

    socket.on('disconnect', function () { });           

    socket.on('bcast', function (data) {        
        socket.emit('news', { 'data': data });
        socket.broadcast.emit('news', { 'data': data });     
    });

    socket.on('login', function(data){
      socket.emit('login', {'data': [ socket.id, data ] });
    });
   });
 });

For example if a client uses chrome developer tools to do the flowing code

 for(var i = 0; i<99999999999; i++)
 {
        socket.emit('bcast', {data: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'});
 }

its going to kill the server.

4 Answers

The rate-limiter-flexible Node.js package can be used against DDoS attacks.

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

const rateLimiter = new RateLimiterMemory({
  points: 5, // 5 points
  duration: 1 // per second
});

socket.on('bcast', data => {
  rateLimiter.consume(uniqueSocketId) // consume 1 point per event
    .then(() => {
      socket.emit('news', { 'data': data });
      socket.broadcast.emit('news', { 'data': data });
    })
    .catch(rejRes => {
      // no available points to consume
      // emit error or another workaround
    });
});

Any event will be blocked, if it happens more than 5 times per second.

There is also the option for distributed applications using Redis. And some flexible settings like insurance and block strategy makes rate-limiter-flexible highly available and fast.

Related