Какие есть хорошие способы предотвращения мошенничества в многопользовательских играх JavaScript?
Представьте себе космического шутера с прокруткой уровня. Какие существуют методы, чтобы предотвратить изменение игры злонамеренным игроком? Вещи, которые он мог сделать, которые сложно ограничить на стороне сервера, - это автоматическое прицеливание, просмотр вне видимой области, быстрое взлом и другие вещи.
Какие есть способы предотвратить это? Предположим, что сервер является любым языком и что клиенты подключены через WebSocket.
Всегда предполагайте, что код может быть взломан на 100%. Подумайте, как предотвратить полностью измененный (в целях мошенничества) клиент. Это могут быть такие вещи, как методы написания безопасного протокола игры, обнаружение на стороне сервера и т. Д.
8 ответов
Сервер король. Клиенты взломаны.
То, что вы хотите сделать, это две вещи с вашей websocket.
Отправлять игровые действия на сервер и получать состояние игры с сервера.
Вы отображаете состояние игры. и вы отправляете ввод на сервер.
- автоматическое наведение - это трудно решить. Вы должны пойти на реализм. Если пользователь наносит 10 выстрелов в голову за 10 мс, вы его пинаете Напишите умный алгоритм обнаружения читов.
- просмотр вне видимой области - решается только отправкой видимой области каждому клиенту
- ускорение взлома - решается путем правильной обработки ввода. Вы получаете событие, когда пользователь продвигается вперед, и вы контролируете, как быстро он идет.
Вы не можете решить эти проблемы путем минимизации кода. Код на клиенте ТОЛЬКО там для обработки ввода и отображения вывода. ВСЕ логика должна быть сделана на сервере.
Вам просто нужно написать проверку на стороне сервера. Единственное, что входные данные для игры значительно сложнее проверить, чем входные данные из-за сложности. Это то же самое, что вы сделали бы, чтобы обезопасить формы.
Вы должны быть действительно осторожны с вашим обнаружением "вход действителен". Вы не хотите выгнать / запретить высококвалифицированных игроков из вашей игры. Очень трудно соблюсти баланс слишком слабой при обнаружении ботов и слишком строгой при обнаружении ботов. В целом сфера обнаружения ботов очень сложна. Например, у Quake было автоматическое обнаружение прицела, которое отбросило умелых игроков в тот же день.
Что касается остановки подключения ботов к вашей веб-розетке, то для дополнительной безопасности установите отдельный канал проверки HTTP или HTTPS в многопользовательской игре. Используйте несколько каналов Http/https/ws, чтобы подтвердить, что клиент является "официальным", выступая в качестве некоторой формы рукопожатия. Это сделает подключение к ws напрямую сложнее.
Пример:
Подумайте о простой многопользовательской игре. 2D гоночная игра на основе комнаты. До n пользователей идут по плоской 2D платформерной карте и мчатся, чтобы добраться от А до Б.
Допустим, ради аргументов, что у вас есть надежная система, в которой сложная аутентификация проходит по каналу HTTPS, так что пользователи не могут получить прямой доступ к вашему каналу веб-сокета и вынуждены проходить через браузер. У вас может быть расширение Chrome, которое имеет дело с аутентификацией, и вы заставляете пользователей использовать это. Это уменьшает проблемную область.
Ваш сервер будет отправлять все визуальные данные, необходимые клиенту для отображения экрана. Вы не можете скрыть эти данные. Неважно, что вы попробуете, глупый хакер может взять ваш код и замедлить его в отладчике, редактируя его по ходу, пока у него не останется примитивная оболочка вокруг вашей веб-сокета. Он позволяет вам выполнить полную аутентификацию, но вы ничего не можете сделать, чтобы он не удалял любой JavaScript, который вы пишете, чтобы он не делал этого. Все, что вы можете достичь, это ограничить количество хакеров, достаточно опытных для доступа к вашей веб-розетке.
Таким образом, хакер теперь держит вашу веб-розетку в песочнице Chrome. Он видит вход. Конечно, ваш гоночный курс генерируется динамически и уникально. Если у вас их было определенное количество, то хакер может заранее спроектировать оптимальный маршрут гонки. Данные, которые вы отправляете для визуализации этой карты, могут отображаться быстрее, чем взаимодействие человека с вашей игрой, и оптимальные ходы для победы в гоночной игре можно рассчитать и отправить на ваш сервер.
Если вы попытаетесь забанить игроков, которые слишком быстро отреагировали на данные вашей карты и называют их ботами, то хакер исправит это и добавит задержку. Если вы попытаетесь забанить игроков, которые играют слишком идеально, то хакер настроит это и сыграет менее, чем идеально, используя случайные числа. Если вы разместите на своей карте ловушки, в которые попадают только алгоритмические боты, их можно избежать, узнав о них, методом проб и ошибок или алгоритмом машинного обучения. Вы ничего не можете сделать, чтобы быть абсолютно в безопасности.
У вас есть только один вариант, чтобы полностью избежать хакеров. То есть создать свой собственный браузер, который нельзя взломать. Встроить механизмы безопасности в браузер. Не позволяйте пользователям редактировать JavaScript во время выполнения в режиме реального времени.
На стороне сервера есть 2 варианта:
1) Полная серверная игра
Каждый клиент отправляет свои "действия" на сервер. Сервер выполняет их и отправляет соответствующие данные обратно. Например, корабль хочет двигаться на север, сервер рассчитывает свою новую позицию и отправляет ее обратно. Сервер также отправляет список видимых кораблей (решение картхаков) и так далее.
2) Полная клиентская игра
Каждый клиент по-прежнему отправляет свои действия на сервер. Но чтобы уменьшить нагрузку на сервер, сервер не выполняет действия, а перенаправляет их всем остальным клиентам. Затем клиенты разрешают все действия одновременно. В результате каждый клиент должен получить одинаковую игру. Периодически каждый клиент отправляет свои абсолютные данные (позиции судна и т. Д.) На сервер, и сервер проверяет, все ли данные клиента идентичны. В противном случае игры не синхронизированы, и кто-то должен взломать.
Недостатком второго метода является то, что некоторые хаки остаются незамеченными: например, карта. Мошенник может внедрить код, чтобы он все видел, но все равно отправлял на сервер только те данные, которые он обычно должен видеть.
-
На стороне клиента есть 1 вариант: компонент javascript, который сканирует игровой код, чтобы увидеть, было ли что-либо изменено (например, код изменен для отображения объектов, которые не видны, но отправляют различные данные проверки на сервер).
Очевидно, что хакер мог легко отключить этот компонент. Чтобы исправить это, вы можете заставить клиента периодически перезагружать компонент с сервера (сервер может проверять, запрашивал ли пользователь файл сценария периодически). Это создает новую проблему: хакер просто периодически запрашивает компонент через AJAX, но не дает ему работать. Чтобы избежать этого: перезагружайте сам компонент, но немного измененную версию самого себя.
Например: компонент должен находиться по адресу yoursite/cheatdetect.js? Control=5. Сервер сгенерирует слегка измененный cheatdetect.js, так что на следующей итерации необходимо загрузить cheatdetect.js? Control=22 (например). Если механизм управления достаточно сложен, хакер не сможет предсказать, какой контрольный номер будет запрашиваться следующим, и cheatdetect.js должен быть выполнен, чтобы продолжить игру.
Обфусцируйте ваш клиент как можно больше кода. Кроме того, используйте немного магии.
Некоторые другие методы, которые можно реализовать:
- Сделайте целевые элементы сложными, чтобы скрипт мог отличить их от других элементов. По возможности избегайте div с предсказуемыми именами классов и идентификаторов. Внедрить стили с помощью JavaScript вместо использования классов. Думайте как хакер и усложняйте себе задачу.
- Используйте ловушки, по которым будет запускаться сценарий. Например, если вектор угрозы представляет собой алгоритм очистки экрана с использованием цветов пикселей, добавьте некоторые общие цвета пикселей в нецелевые элементы. Удары по этим нецелевым объектам могут показаться читеру несущественными, но их можно будет обнаружить. Вы же не хотите, чтобы мошенник знал, почему вы это знаете.
- Ограничьте минимальное время между действиями чуть ниже человеческого уровня. Лучшие игроки выйдут на это плато, и не будет иметь большого значения, кто жульничает, и сразу же смогут обнаружить любого, кто пишет скрипты быстрее, чем это, путем побочного вызова методов.
- Генераторы случайных чисел обычно единообразны. Человеческой природы нет. Скорее всего, генератор случайных чисел будет иметь значения в пределах установленного лимита и равномерное распределение. Естественное распределение представляет собой гауссову кривую. Если вы выбрали распределение, и оно выглядит как прямоугольная волна на осях x и y, 100% это обман. Обманщику будет довольно сложно определить порог для алгоритма, потому что это производная случайного, а не само случайное распределение. Вы также используете совокупные данные, а не отдельные игры для его обнаружения, поэтому обратное проектирование алгоритма было бы чрезвычайно трудным без знания вашего алгоритма обнаружения.
- По возможности используйте энтропию. Избегайте предсказуемых игр. Представьте себе гоночную игру по набору гоночных трасс. Каждый игровой процесс может иметь несколько разные уровни тяги, мощности и импульса. Сценарий должен быть очень хорош, чтобы победить его. В игре с прокруткой вы можете изменять факторы, которые инстинктивны для людей, но трудны для компьютеров, такие как сила ветра, изменения гравитации и т. Д. Это также сделало бы ее более интересной в качестве побочного преимущества.
- Сгенерированные сервером токены могут использоваться для проверки использования элементов пользовательского интерфейса, а не для вызовов самого кода. Проверка может выполняться за один вызов в конце игры, сравнивая события с хешированными кодами элементов пользовательского интерфейса. Токен должен быть хешем с закрытым ключом сервера и некоторым значением элемента пользовательского интерфейса.
- Обманывайте читера данными, которые, по их мнению, вы используете для обнаружения читов. Например, вызовы метода DetectCheat с фиктивными вызовами поддельного бэкэнда. Это старый фокус фокусника. Помашите здесь рукой, а другой рукой опустите карту в колоду. Пусть они тратят дни напролет в лабиринте, у которого нет выхода, и выдергивают много волос.
Вы ничего не можете сделать, чтобы никто не мог изменить ваш JS или написать скрипт GreaseMonkey. Однако вы можете усложнить им задачу, свернув сценарий и сделав свой код максимально загадочным. Может быть, даже добавив некоторые фальшивые методы или переменные, которые ничего не делают, но используются, чтобы отбросить атакующего. Но при наличии достаточного количества времени ни один из этих методов не является абсолютно надежным, поскольку, как только ваш код отправляется клиенту, он больше не ваш.
Им не нужно прикасаться к вашему клиентскому коду - они могут просто понюхать и реализовать ваш протокол Websocket и написать крошечного агента, который притворяется человеком-игроком.
Обновление: проблема состоит из нескольких частей, и у меня нет ответов на все вопросы, но различные варианты могут быть оценены с учетом этих вопросов:
- Как далеко вы готовы пойти, чтобы предотвратить обман? Если вы заботитесь только о случайном мошенничестве, сколько барьеров достаточно, чтобы обескуражить случайного мошенника? Промежуточный программист Javascript? Серьезный эксперт? Взвешивая это в сравнении с преимуществами мошенничества, есть ли что-то реальное на кону, например, деньги и призы, или просто репутация?
- Как вы получаете высокую уверенность в том, что человек вносит свой вклад в вашу игру? Например, с достаточно хорошей библиотекой компьютерного зрения я мог бы смоделировать вашу игру на отдельном машинном входе для компьютера, изображая из себя мышь, но это имеет высокую относительную стоимость (не стоит моего времени).
- Как вы можете создать цепочку доверия в вашем протоколе, чтобы знания (2) могли передаваться на сервер и чтобы ваш сервер был относительно уверен, что ваш клиентский код отправляет сообщения?
Конечно, многие препятствия, которые вы бросаете, могут быть обойдены стороной, но какова будет цена для вас и игрока? Смотрите раздел "Война на истощение".
Единственный способ, которым я могу даже подумать о реализации этого, - это изменить ваш Javascript для функционирования в качестве клиента, а затем разработать механизм центрального сервера для проверки данных, отправляемых с этого клиента. Это, вероятно, большое изменение для реализации и, скорее всего, сделает ваш проект более сложным. Однако, как было сказано ранее, если приложение выполняется полностью на клиенте, клиент может в значительной степени делать все, что он хочет, с вашим сценарием. Единственный способ обезопасить его - использовать доверенную машину для обработки проверки.
Вы можете редактировать JavaScript в браузере и заставить его работать. Некоторые люди предполагают, что позвонить, чтобы проверить с сервером. Поэтому после совершения звонка на сервер он будет проверен на сервере. После проверки он перейдет на сторону клиента и выполнит действия. Но я думаю, что даже это не является надежным.
Например, для базового действия при входе в систему: в angular при обращении к серверу сервер проверяет имя пользователя & pwd, а при проверке возвращается клиенту и позволяет пользователю войти в систему с помощью angular.
Когда я говорю "вход в систему с помощью angular", он будет хранить в cookie-файлах, например, объекты пользователя и другие вещи. Но, тем не менее, пользователь может удалить код JS, который выполняет вызов к бэкэнду, и вернуть TRUE(там, где это необходимо) и вставить пользовательский объект (фиктивный) в файлы cookie и другие объекты (все, что нужно) и войти в систему. Это очень сложно, но выполнимо. Во многих случаях это нежелательно, даже если для редактирования / взлома кода требуются часы.
Это возможно в одностраничных приложениях, где файлы JS не перезагружаются для каждой страницы. Чтобы уменьшить вероятность взлома, мы можем использовать минимизированные коды. И я думаю, что если такие действия выполняются в бэкэнде (например, вход в Django), это намного безопаснее.
Пожалуйста, поправьте меня, если я ошибаюсь.
Я бы использовал комбинацию минификации и AJAX. Если все функции и данные не загружены на страницу, обмануть будет сложнее.
С другой стороны, моддинг оказался очень прибыльным инструментом для таких компаний, как Id Software. Возможно, изменение системы может сделать игру более приятной для сообщества в целом.