mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-07-10 16:32:11 +02:00
closes #2432
This commit is contained in:
@@ -6,9 +6,11 @@ var app,
|
||||
},
|
||||
async = require('async'),
|
||||
path = require('path'),
|
||||
csrf = require('csurf'),
|
||||
winston = require('winston'),
|
||||
validator = require('validator'),
|
||||
nconf = require('nconf'),
|
||||
|
||||
plugins = require('./../plugins'),
|
||||
meta = require('./../meta'),
|
||||
translator = require('./../../public/src/translator'),
|
||||
@@ -18,7 +20,6 @@ var app,
|
||||
topics = require('./../topics'),
|
||||
messaging = require('../messaging'),
|
||||
ensureLoggedIn = require('connect-ensure-login'),
|
||||
csrf = require('csurf'),
|
||||
|
||||
controllers = {
|
||||
api: require('./../controllers/api')
|
||||
|
||||
35
src/middleware/ratelimit.js
Normal file
35
src/middleware/ratelimit.js
Normal file
@@ -0,0 +1,35 @@
|
||||
|
||||
|
||||
'use strict';
|
||||
var winston = require('winston');
|
||||
|
||||
var ratelimit = {};
|
||||
|
||||
var allowedCallsPerSecond = 10;
|
||||
|
||||
|
||||
ratelimit.isFlooding = function(socket) {
|
||||
socket.callsPerSecond = socket.callsPerSecond || 0;
|
||||
socket.elapsedTime = socket.elapsedTime || 0;
|
||||
socket.lastCallTime = socket.lastCallTime || Date.now();
|
||||
|
||||
++socket.callsPerSecond;
|
||||
|
||||
var now = Date.now();
|
||||
socket.elapsedTime += now - socket.lastCallTime;
|
||||
|
||||
if (socket.callsPerSecond > allowedCallsPerSecond && socket.elapsedTime < 1000) {
|
||||
winston.warn('Flooding detected! Calls : ' + socket.callsPerSecond + ', Duration : ' + socket.elapsedTime);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (socket.elapsedTime >= 1000) {
|
||||
socket.elapsedTime = 0;
|
||||
socket.callsPerSecond = 0;
|
||||
}
|
||||
|
||||
socket.lastCallTime = now;
|
||||
return false;
|
||||
};
|
||||
|
||||
module.exports = ratelimit;
|
||||
@@ -15,6 +15,7 @@ var SocketIO = require('socket.io'),
|
||||
topics = require('../topics'),
|
||||
logger = require('../logger'),
|
||||
meta = require('../meta'),
|
||||
ratelimit = require('../middleware/ratelimit'),
|
||||
|
||||
Sockets = {},
|
||||
Namespaces = {};
|
||||
@@ -195,16 +196,13 @@ Sockets.init = function(server) {
|
||||
});
|
||||
|
||||
socket.on('*', function(payload, callback) {
|
||||
function callMethod(method) {
|
||||
method.call(null, socket, payload.args.length ? payload.args[0] : null, function(err, result) {
|
||||
if (callback) {
|
||||
callback(err?{message:err.message}:null, result);
|
||||
}
|
||||
});
|
||||
if (!payload.name) {
|
||||
return winston.warn('[socket.io] Empty method name');
|
||||
}
|
||||
|
||||
if(!payload.name) {
|
||||
return winston.warn('[socket.io] Empty method name');
|
||||
if (ratelimit.isFlooding(socket)) {
|
||||
winston.warn('[socket.io] Too many emits! Disconnecting ' + socket.uid);
|
||||
return socket.disconnect();
|
||||
}
|
||||
|
||||
var parts = payload.name.toString().split('.'),
|
||||
@@ -226,15 +224,23 @@ Sockets.init = function(server) {
|
||||
|
||||
if (Namespaces[namespace].before) {
|
||||
Namespaces[namespace].before(socket, payload.name, function() {
|
||||
callMethod(methodToCall);
|
||||
callMethod(methodToCall, socket, payload, callback);
|
||||
});
|
||||
} else {
|
||||
callMethod(methodToCall);
|
||||
callMethod(methodToCall, socket, payload, callback);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
function callMethod(method, socket, payload, callback) {
|
||||
method.call(null, socket, payload.args.length ? payload.args[0] : null, function(err, result) {
|
||||
if (callback) {
|
||||
callback(err ? {message: err.message} : null, result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Sockets.logoutUser = function(uid) {
|
||||
Sockets.getUserSockets(uid).forEach(function(socket) {
|
||||
if (socket.handshake && socket.handshake.signedCookies && socket.handshake.signedCookies['express.sid']) {
|
||||
|
||||
Reference in New Issue
Block a user