Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node socket.io, anything to prevent flooding?

How can I prevent someone from simply doing

while(true){client.emit('i am spammer', true)};

This sure proves to be a problem when someone has the urge to crash my node server!

enter image description here

like image 409
Justin Avatar asked Mar 01 '14 04:03

Justin


1 Answers

I implemented a little flood function, not perfect (see improvements below) but it will disconnect a user when he does to much request.

// Not more then 100 request in 10 seconds
let FLOOD_TIME = 10000;
let FLOOD_MAX = 100;

let flood = {
    floods: {},
    lastFloodClear: new Date(),
    protect: (io, socket) => {

        // Reset flood protection
        if( Math.abs( new Date() - flood.lastFloodClear) > FLOOD_TIME ){
            flood.floods = {};
            flood.lastFloodClear = new Date();
        }

        flood.floods[socket.id] == undefined ? flood.floods[socket.id] = {} : flood.floods[socket.id];
        flood.floods[socket.id].count == undefined ? flood.floods[socket.id].count = 0 : flood.floods[socket.id].count;
        flood.floods[socket.id].count++;

        //Disconnect the socket if he went over FLOOD_MAX in FLOOD_TIME
        if( flood.floods[socket.id].count > FLOOD_MAX){
            console.log('FLOODPROTECTION ', socket.id)
            io.sockets.connected[socket.id].disconnect();
            return false;
        }

        return true;
    }
}

exports = module.exports = flood;

And then use it like this:

let flood = require('../modules/flood')

// ... init socket io...

socket.on('message', function () {
    if(flood.protect(io, socket)){
        //do stuff
    }   
});

Improvements would be, to add another value next to the count, how often he got disconneted and then create a banlist and dont let him connect anymore. Also when a user refreshes the page he gets a new socket.id so maybe use here a unique cookie value instead of the socket.id

like image 105
kenny Avatar answered Oct 16 '22 08:10

kenny