Socket.IO защита сокета без аутентификации - PullRequest
0 голосов
/ 31 декабря 2018

Я создал простое приложение Node.js, используя Express.js и socket.io (доступно здесь ), где пользователь нажимает кнопку, и оно увеличивает число на странице.Этот номер также увеличивается в реальном времени среди всех клиентов, подключенных к странице.Я использую веб-сокеты и socket.io для получения системы связи между клиентом и сервером и обновления живого номера.

Я использую модуль защита от затопления , чтобы ограничить выброс сокетов до 5 в секунду, но это на самом деле не делает игру очень увлекательной из-за небольшого количества кликов в секунду, которое вы можете иметь, и хакеры могут просто использовать setInterval и все же добиваться значительного прогресса автоматически, даже с такой низкой скоростью.

Моя проблема:

  1. Я не хочу, чтобы пользователь проходил аутентификацию - любой должен иметь возможность играть!

  2. Я хочу сохранить частоту кликов около 15 кликов в секунду, если это возможно.

  3. Я не хочу, чтобы люди могли отправлять сообщения сокетов и автоматически нажимали кнопку в браузереconsole.

Вот программа :

index.js

var express = require("express");
var http = require("http");
var socketIO = require("socket.io");
var path = require("path");
var fs = require("fs");
var FloodProtection = require("flood-protection").default;
__dirname = path.resolve();

function btoa(str) {
  return new Buffer(str, 'latin1').toString('base64');
};

function atob(b64Encoded) {
  return new Buffer(b64Encoded, 'base64').toString('latin1');
};

var app = express();
app.get("/", function(req, res){
  res.sendFile(__dirname + "/index.html");
});

var temp;
num = temp | parseInt(atob(fs.readFileSync("num.txt"))) | 0

var server = http.createServer(app);
var io = socketIO.listen(server, {log: true});
io.sockets.on("connection", (socket) => {
  protector = new FloodProtection({rate: 5, per: 1})
  io.sockets.emit("update", num);
  socket.on("push", (value) => {
    if (protector.check()) {
      num++;
      temp = num
      io.sockets.emit("update", temp);
    } else {
      io.sockets.emit("update", "You can only click the button five times per second.")
      socket.disconnect(2)
      setTimeout(()=>{}, 3000)
    }
  });
  socket.on("disconnect", () => {
    fs.writeFile("num.txt", btoa(String(temp)), (err) => {
      if (err) throw err;
      console.log("saved | new num: " + temp);
    })
  })
});

server.listen(5000);

index.html

<html>
  <head>
    <title>A Button</title>
  </head>
  <body>
    <button onclick='push();'>Click me!</button>
    <p id="out"></p>
  </body>
  <script type="text/javascript" src="/socket.io/socket.io.js"></script>
  <script type="text/javascript">
    var variableFromFrontEnd = 2;
    var socket = io.connect("/");
    socket.on("connect", function() {
      socket.on("update", function(val) {
        document.getElementById("out").innerHTML = val
      });
    });
    socket.on("disconnect", function() {
      setTimeout(()=>{socket.connect();}, 1000);
    });
    function push() {
      if (socket.connected) {
        socket.emit("push");
      }
    }
  </script>
</html>

num.txt - это кодированное число base-64.

Итак, есть ли способ сделать это без значительного ограничения скорости или аутентификации?Или мне просто нужно использовать ограничение скорости?

1 Ответ

0 голосов
/ 01 января 2019

Существует множество различных способов обмана пользователей и столько же способов их предотвращения.Общее правило состоит в том, что вы можете только «усложнить ситуацию» (если вам повезет, достаточно сложно, чтобы потенциальный обманщик потерял интерес перед успехом).

В браузерной игре я бы позаботился о том, чтобывы по крайней мере гарантируете, что ваша игра будет полностью минимизирована / ограничена (таким образом, ваш код javascript настолько нечитабелен, насколько это возможно, и сложнее просто вызвать функцию "щелчка" напрямую), и встроите контрольные суммы в свойсообщения (таким образом, пользователь не может просто сделать вызовы сокета напрямую на сервер).

После того, как вы это сделаете, вам все равно придется иметь дело с пользователями, которые генерируют события щелчка на элементе напрямую с помощью кода илиплагин, или пользователи, которые используют программу вне браузера , чтобы повторно генерировать события нажатия над кнопкой.Ваша лучшая защита против этого - не предотвратить , а вместо этого обнаружить это - вероятно, на стороне сервера, наблюдая за пользователями, которые имеют устойчивую частоту кликов, которая не является человеческойвозможно, а затем взорвать их игру / временно запретить их IP / и т. д.

См. связанный вопрос Способы предотвращения или уменьшения мошенничества для более связанных идей (этот вопрос о общих клиент-серверные игры, а не браузерные игры, но некоторые обсуждения все еще полезны).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...