3

我正在制作一个基于玩家能够邀请其他玩家参加聚会的网页,以及其他一些事情。

我有您聚会中聊天/用户的基本发送/接收/更新。唯一的问题是,是什么阻止某人坐在那里打开开发者控制台并继续

socket.emit('updateUsers', 'Weiner');
socket.emit('updateUsers', 'Idiot');
socket.emit('updateUsers', 'Bad word');
socket.emit('updateUsers', 'Other stupid malicious really long spam the chat name');

我怎样才能防止这种情况,使他们不能做这样的事情?

(完整的 JS 堆栈,Node.js)谢谢!

4

5 回答 5

4

我也遇到了这个问题,这是我的解决方案,就垃圾邮件发出去(恶意套接字使用)..

var spamData = new Object();
var spamCheckFunctions = ["updateUsers","moreEmits"]; // anti-spam will check these socket emits
var antiSpam = 3000; // anti spam check per milliseconds
var antiSpamRemove = 3; // -spam points per antiSpam check
var maxSpam = 9; // Max spam points before disconnect is thrown to the socket

io.sockets.on('connection', function (socket) {

    // Spam Check, this binds to all emits
    var emit = socket.emit;
    socket.emit = function() {
        data = Array.prototype.slice.call(arguments);
        if(spamCheckFunctions.contains(data[0])){
            addSpam(socket);
        };
        emit.apply(socket, arguments);
    };

    var $emit = socket.$emit;
    socket.$emit = function() {
        data = Array.prototype.slice.call(arguments);
        if(spamCheckFunctions.contains(data[0])){
            addSpam(socket);
        }
        $emit.apply(socket, arguments);
    };

});


function maxSpamCheck(socket){
    if(spamData[socket.username].spamScore>=maxSpam && !socket.spamViolated){
      socket.spamViolated = true;
      socket.disconnect();

   }
}
function checkSpam(){
    for(user in spamData){
        if(spamData[user].spamScore>=1) spamData[user].spamScore-=antiSpamRemove;
    }
    return;
}
setInterval(checkSpam,antiSpam);

function addSpam(socket){
    if(socket.spamViolated) return;
    spamData[socket.username].spamScore+=1;
    maxSpamCheck(socket);
}


// Then add this where your user is authenticated
function authenticate(socket){
    socket.username = username // here you define username
    socket.spamViolated = false;

    spamData[socket.username] = {
        spamScore: 0
    }
}

Array.prototype.contains = function(k) {
    for(var p in this)
        if(this[p] === k)
            return true;
    return false;
};

基本上绑定到所有发射并检查发射名称是否包含在spamCheckFunctions如果它是它会添加一个垃圾邮件点,如果用户超过垃圾邮件分数量(maxSpam); 他将断开连接。并且对于任意定义的每毫秒antiSpam减去定义的用户垃圾邮件分数antiSpamRemove

我确信有更清洁的解决方案,但这个解决方案对我来说非常好:)

只需确保验证/验证用户。

这就是我对它们进行身份验证的方式(不使用 nodejs 作为网络服务器,而是使用 django):

io.configure(function(){
    io.set('authorization', function(data, accept){
        if(data.headers.cookie){
            data.cookie = cookie_reader.parse(data.headers.cookie);
            return accept(null, true);
        }
        return accept('error', false);
    });
});

现在您可以访问socket.handshake.cookie['sessionid'](在我的情况下,这与 django 一起使用)然后与socket.handshake.cookie['sessionid']您的会话存储在网络服务器上的条目匹配

于 2014-01-07T09:26:14.270 回答
1

这是一个普遍的难题。你可以做两件事:

1)在客户端使用自调用函数,即

(function(w) {
    // define your sockets here
    var socket = ...;
})(window);

显然它在客户端,所以这不是很安全。但是有这样的墙也不错。

2) 在服务器端跟踪发布频率。例如,如果有人在一秒钟内发帖 5 次,那么您可以假设它是垃圾邮件,您可以阻止该套接字。如果结合身份验证和复杂的注册(因此人们在创建新帐户时会遇到问题),它会特别有效。

于 2014-01-07T09:41:20.710 回答
0

使用行为类似于 cookie 的 md5/sha 密钥。

为特定用户生成密钥并将其发送到客户端并始终检查传入请求是否具有相同的密钥

它不会完全安全,因为黑客总是可以在源代码或 localStorage 中找到您的密钥,但会尝试通过混淆您的代码来隐藏它

于 2013-05-23T17:01:40.760 回答
0

使用rate-limiter-flexible包来限制每秒的事件数。通过IP限制是最简单的,但如果可能的话最好通过userId限制。

const app = require('http').createServer();
const io = require('socket.io')(app);
const { RateLimiterMemory } = require('rate-limiter-flexible');

app.listen(3000);

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

io.on('connection', (socket) => {
  socket.on('bcast', async (data) => {
    try {
      await rateLimiter.consume(socket.handshake.address); // consume 1 point per event from IP
      socket.emit('news', { 'data': data });
      socket.broadcast.emit('news', { 'data': data });
    } catch(rejRes) {
      // no available points to consume
      // emit error or warning message
      socket.emit('blocked', { 'retry-ms': rejRes.msBeforeNext });
    }
  });
});

在官方文档中阅读更多内容

于 2019-02-10T05:59:02.970 回答
0

防止垃圾邮件的一种方法是实施用户身份验证和/或数据包速率限制器。添加一个中间件函数,用于跟踪 socketId 和通过该套接字发送的数据包数量。当它超过你的限制时断开套接字。

您甚至可以添加一个额外的功能来跟踪该套接字的 IP 地址,如果 IP 地址由于垃圾邮件而经常断开连接,您可以禁止该 IP。添加一个检查您的连接事件允许哪些 IP 地址。

于 2017-07-25T10:52:42.590 回答