Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 213
Virushan Avatar asked Dec 06 '13 23:12

Virushan


People also ask

What strategy is the better to prevent a DoS attack on your Nodejs application?

Avoid DOS attacks by explicitly setting when a process should crash. Otherwise: This is just an educated guess: given many Node. js applications, if we try passing an empty JSON body to all POST requests — a handful of applications will crash.

How do you defend a denial of service attack?

There are several approaches you can take to defend against a DDoS attack: Black-holing or sinkholing: This approach blocks all traffic and diverts it to a black hole, where it is discarded. The downside is that all traffic is discarded -- both good and bad -- and the targeted business is taken off-line.

Can a distributed denial of service attack be totally prevented?

Defending Against DDoS Attacks It is much harder to respond after an attack is already under way. While DDoS attacks can't be prevented, steps can be taken to make it harder for an attacker to render a network unresponsive.

What type of devices could be used to conduct a distributed denial of service attack?

Botnets, which are vast networks of computers, can be used to wage DDoS attacks. They are usually composed of compromised computers (e.g., IoT devices, servers, workstations, routers, etc.), or zombies, that are controlled by a central server. Attackers don't necessarily need a botnet to conduct a DDoS attack.


2 Answers

Look into JS event throttling and debouncing!

Those techniques will help you prevent and detect attacks to a certain point (which is, in my opinion, enough for a small multiplayer socket game)...

EDIT:

In this jsfiddle: http://jsfiddle.net/y4tq9/9/

var sIO = {};  sIO.on = (function(){     var messages = {};     var speedLimit = 5; //5ms     return function(message, handler) {         messages[message] = messages[message] || {};         if(messages[message].timestamp && new Date().getTime() - messages[message].timestamp < speedLimit) return false;         else messages[message].timestamp = new Date().getTime();          handler();         return true;         //execute code, Ex:     } }()); 

you can see that every request sent faster than 5ms will return false, otherwise the handler get run.

You simple disconnect the sockets who send request faster than 5ms (or 2ms, or 3ms depending on your network and your application's weight...).

You might as well using js event throttling on client site to make sure all of your requests doesn't send faster than the speed limit!

This technique will not provide absolute protection from exploiting, but it will prevent your server from crashing when attackers try to Dos...

like image 103
Keo Strife Avatar answered Oct 10 '22 04:10

Keo Strife


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.

like image 33
Animir Avatar answered Oct 10 '22 04:10

Animir