Подтвердить что ты не робот

Счет игры основан на обратном отсчете на стороне клиента. Как пуленепробивать его?

Я работаю над игрой, у которой есть счет, основанный на обратном отсчете JavaScript: чем быстрее вы закончите уровень до того, как обратный отсчет достигнет нуля, тем больше будет ваш счет.

Как я могу убедиться, что он каким-то образом не изменен, когда я, наконец, получаю его с клиентской стороны на стороне сервера?

Моя первоначальная идея состоит в том, чтобы сделать две контрольные точки: одну в начале уровня и другую в конце. Контрольная точка - это в основном сеанс, отправленный через AJAX на серверный PHP script, который затем присваивается по времени. Таким образом, после завершения игры на стороне клиента оценка проверяется на стороне сервера. Является ли такая защита хорошей?

Заранее благодарю вас!

EDIT: Я также открыт для любых других способов достижения желаемой функциональности.

4b9b3361

Ответ 1

Как указывали другие, вы не можете быть уверены, что время не подделано, однако есть способы смягчить последствия:

Если у вас есть (серверная) система, которая подозревает, что оценки были подделаны, вы можете занести в черный список этот IP-адрес или файл cookie и не показывать эти оценки другим пользователям. Однако покажите оценки для хакера. Это имеет несколько эффектов: во-первых, если они думают, что они избили вас, они могут двигаться дальше и оставлять ваш код в покое. Во-вторых, если ваше обманное поведение ошибочно полагает, что игрок ниндзя взломал, игрок все равно будет видеть свой счет в таблицах как обычно (даже если другие игроки этого не делают). Следовательно, ложные срабатывания не имеют большого значения, и вы можете использовать более сложные алгоритмы, например. Как этот показатель улучшения игрока сравнивается со средним? Он получил кучу плохих оценок, а затем неожиданно невероятный? Мой сервер видел необычную картину хитов от этого пользователя? Etc.

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

Ответ 2

Просто сохраните значение в поле datetime в вашей базе данных. Затем вы засеваете свой javascript с этим значением. Таким образом, любое изменение на стороне клиента не повлияет на сохраненное время.

Однако, если вы зависите от клиентской стороны, чтобы получить значение, вы не можете ничего сделать, чтобы убедиться в его правильности. Пользователь все еще может обмануть запрос ajax без реальной проблемы. Это делает его немного затрудненным, но, безусловно, выполнимым.

Как только ваш обратный отсчет каким-то образом связан с клиентской стороной, нет выхода:)

Ответ 3

Есть два возможных сценария, с которыми вы можете столкнуться. Позвольте мне начать с простого:

a) Если веб-приложение разработано таким образом, что игра начинается, как только загружается страница, ваша жизнь будет простой. script, который отправляет игру, должен помечать базу данных со временем, в которое была отправлена ​​игра. Это будет время начала. Время окончания записи будет записано, когда клиент отправит сообщение "уровень завершен". Поскольку время записывается на серверной стороне в обоих случаях, клиенту не требуется держать время. Однако есть улов. См. Раздел Поймать ниже.

b) Если клиент загружает приложение, но игра начинается намного позже, когда пользователь нажимает "играть" и т.д., ваша жизнь будет немного сложнее. В этом случае вам понадобится "уровень начался", а также сообщение "уровень завершен", поступающий от клиента. Опять же, было бы лучшей идеей держать время на сервере, а не на клиенте. Тем не менее, вам нужно будет убедиться, что клиент получает ACK до сообщения "начального уровня" перед началом игры, чтобы гарантировать, что пользователь не играет в игру, которая не записывается сервером. (Сообщение "уровень началось", возможно, никогда не дошло до сервера).

Catch: вам нужно понять, что существует без защиты для пользователя, обманывающего его результаты! JS полностью открыт, и независимо от того, как вы реализуете свои начальные/конечные вызовы на сервер, любой пользователь может написать script для отправки подобных вызовов на сервер в любой промежуток времени, который она хочет использовать. Даже если вы используете сеанс/файл cookie, их можно легко воспроизвести. (Например, с помощью сниффера). Таким образом, вы должны понимать и принимать ограничения дизайна, налагаемые архитектурой и кодом HTML/JS в этих пределах. Следовательно, лучшая идея заключается в писать код для пользователей, а не для того, чтобы хакеры не могли отправлять вызовы изгоев. Сделайте вашу игру забавой для людей, которые будут играть в вашу игру, и не волнуйтесь о том, что хакеры обманывают свои оценки - они все равно не будут вашей целевой аудиторией.

Ответ 4

Прежде всего, забудьте получить истекшее время со стороны клиента. Любой злоумышленник может изменять отправленные данные.

Сторона сервера должна быть единственным органом для хранения времени. В начале уровня сохраните текущее время в $_SESSION. В конце уровня вычтите его из текущего времени, и это истекшее время для уровня.

$_SESSION['start_time'] = time();

$elapsed_time = time() - $_SESSION['start_time'];

Вы все же можете показать прошедшее время Javascript для удобства пользователя. Для разницы во времени между клиентом и сервером (что вполне возможно) вы можете выполнять синхронизацию, получая время elapsed_time, когда ваш клиент попадает на сервер.

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

Ответ 5

Вы можете использовать временную метку в сеансе, чтобы сохранить дату начала, а затем отправить запрос сделать запрос JavaScript, когда игрок сделал (но вторая метка времени должна поступать с PHP или на другом языке на стороне сервера). Обидный действительно пуленепробиваемый способ - ничего не показывать пользователю и просить его рассказать вам каждый ход, проверить его с сервером и отправить обратно то, что он позволяет ему узнать. Но это означает задержку.

Ответ 6

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

Этот токен должен быть действителен только для одного запроса. В сочетании с упомянутыми решениями (проверка на основе сервера и т.д.) Вы должны иметь возможность создавать надежную систему подсчета очков.

Ответ 7

Хорошо, думая об этой проблеме, дает мне две идеи:

  • Атакуйте свой собственный сервер. я имею в виду, посылать запрос каждые 1 секунду, который сохранит счет. таким образом, "хакер" не может отправить время начала/окончания и обмануть.

  • делает запросы в определенное время различными. хорошо, так что скажем, что мы начали играть, вы можете отправить запрос с определенными интервалами времени (3,4 с?) если запрос не находится в этом временном кадре, тогда пользователь обманывает? или, по крайней мере, отмечен как возможный мошенник.

  • используйте простую строку. XD для времени начала/окончания, отправленного на сервер, в отключенном состоянии. вы можете попробовать jCryption для шифрования.

поскольку, как говорили другие, он не является полностью отказоустойчивым (поскольку мы говорим о стороне клиента script), но, по крайней мере, это будет намного сложнее обмануть. dunno, его просто мои два цента.

Ответ 8

Невозможно сделать это на 100% пуленепробиваемым, вы можете только усложнить его взломать, если он основан на клиентской стороне

Ответ 9

Вы можете генерировать GUID, когда страница отображается. Вы можете объединить этот идентификатор GUID, время начала datetime, идентификатор сеанса и вычислить хэш из них для проверки данных при возврате пользователя.