защита от читов для браузерной игры xmlhttp / js / perl / php - PullRequest
5 голосов
/ 17 ноября 2009

Допустим, что в браузерной игре выполнение какого-либо действия (для простоты, скажем, кто-то нажимает на ссылку, которая увеличивает его счет на 100) нажимает на эту ссылку, которая будет иметь URL-адрес, например increase_score.pl?amount=100, какое предупреждение кто-то просто отправляет запросы на веб-сервер для выполнения этой команды:

  1. Снова и снова, фактически не выполняя задачу нажатия на ссылку и
  2. Отправка ложного запроса на сервер, где значение установлено на что-то новое, например 100000.

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

Ответы [ 10 ]

15 голосов
/ 17 ноября 2009

Ничто не может помешать им сделать это, если вы реализуете свою игру так, как вы предлагаете.

Вам необходимо реализовать игровую логику на сервере и назначать очки только после того, как сервер подтвердит действие.

Например: на SO, когда кто-то голосует за ваш вопрос, это не посылается как команда для повышения вашей репутации. Веб-приложение просто говорит серверу, что пользователь X проголосовал за вопрос Y up. Затем сервер проверяет данные и присваивает баллы, если все проверено. (Не сказать, что ТАК игра, но необходимая логика похожа.)

5 голосов
/ 17 ноября 2009

Короткая версия: вы не можете. Каждый фрагмент данных, который вы получаете от клиента (браузера), может быть подделан вручную кем-то, кто знает, что они делают.

Вам необходимо фундаментально переосмыслить структуру приложения. Вам необходимо кодировать серверную часть приложения таким образом, чтобы оно обрабатывало каждый фрагмент данных, поступающих от клиента, как пачку грязной грязной лжи, пока оно не докажет себе, что данные, на самом деле, правдоподобны. Вы должны избегать мысли сервера: «Если клиент говорит мне сделать это, ясно, что разрешено сказать мне, чтобы я сделал это».

НЕПРАВИЛЬНЫЙ ПУТЬ:
Клиент: Игрок Стив говорит, чтобы дать Игроку Стиву один миллион очков.
Сервер: Хорошо!

ПРАВИЛЬНЫЙ ПУТЬ:
Клиент: Игрок Стив говорит, чтобы дать Игроку Стиву один миллион очков.
Сервер: Что ж, позвольте мне сначала проверить, разрешено ли игроку Стиву в данный момент давать один миллиард очков ... ах. Он не Пожалуйста, покажите это сообщение "Go Fsck Yourself, Cheater" игроку Стиву.

Что касается определения того, кто вошел в систему, это просто вопрос передачи клиенту куки с чертовски почти невозможным для угадывания значением, которое вы отслеживаете на сервере - но я предполагаю, что вы знаете как бороться с управлением сессиями. :-) (А если нет, то Google ждет. )

3 голосов
/ 17 ноября 2009

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

HTTP_REFERER может быть подделан любым веб-клиентом.

1 голос
/ 17 ноября 2009

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

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

1 голос
/ 17 ноября 2009

Несколько вещей, на которые стоит обратить внимание.

Во-первых, запросы вашего сервера на что-то вроде этого должны быть POST, а не GET. Только GET-запросы должны быть идемпотентными, и в противном случае является нарушением спецификации HTTP .

Во-вторых, здесь вы видите классическую проблему доверия клиентов . У вас есть , чтобы доверять клиенту при отправке на сервер результатов или другой информации об игровом интервале, но вы не хотите, чтобы клиент отправлял неверные данные. Предотвратить недопустимые действия легко, но предотвращение нечестных данных в действии позволено гораздо более проблематично.

Бен С. замечательно рассказывает о том, как вы разрабатываете протоколы связи между клиентом и сервером, как это. Разрешить отправку значений точек в качестве доверенных данных, как правило, будет плохой идеей. Желательно указать, что действие имело место, и позволить серверу выяснить, сколько очков следует назначить, если оно вообще есть. Но иногда вы не можете обойти это. Рассмотрим сценарий гоночной игры. У клиента есть для отправки времени пользователя, и его нельзя абстрагировать в какой-либо другой вызов, такой как "completeLevelFour". Так что ты сейчас делаешь?

Подход с использованием жетонов, предложенный Ахметом и Дином, является разумным, но не идеальным. Во-первых, токен still должен быть передан клиенту, что означает, что он может быть обнаружен потенциальным злоумышленником и может быть использован злонамеренно. Кроме того, что если ваш игровой API должен быть без сохранения состояния? Это означает, что аутентификация токена на основе сеанса отключена. И теперь вы попадаете в глубокие, темные недра проблемы доверия клиентов.

Мало что можно сделать, чтобы он был на 100% надежным. Но вы можете сделать это очень неудобным чтобы обманывать. Рассмотрим модель безопасности Facebook (каждый запрос API подписан). Это очень хорошо и требует от злоумышленника на самом деле копаться в коде на стороне клиента, прежде чем он сможет понять, как подделать запрос.

Другой подход - воспроизведение сервера. Как и в гоночной игре, вместо того, чтобы просто отправлять на сервер значение «время», есть контрольные точки, которые также записывают время и отправляют их все. Установите реалистичные минимумы для каждого интервала и проверьте на сервере, что все эти данные находятся в установленных пределах.

Удачи!

1 голос
/ 17 ноября 2009

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

Это может варьироваться по сложности в зависимости от того, как часто вы разрешаете клики.

1 голос
/ 17 ноября 2009

токен с cookie / сессией.

0 голосов
/ 16 июля 2011

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

Это также блокирует большинство трюков CheatEngine.

0 голосов
/ 17 ноября 2009

Я бы предложил создать URL, специфичный для каждого действия. Что-то вроде:

/score/link_88_clicked/
/score/link_69_clicked/
/score/link_42_clicked/

Каждая из этих ссылок может делать две вещи:

  1. Отметьте в сеансе, что ссылка была нажата, чтобы она больше не отслеживала эту ссылку.
  2. Добавить к своей оценке.
0 голосов
/ 17 ноября 2009

Расширяя ответ Ахмета, каждый раз, когда они загружают страницу, генерируют случайный ключ. Сохраните ключ в сеансе пользователя. Добавьте случайный ключ к каждой ссылке, чтобы новая ссылка для получения этих 100 баллов была следующей:

increase_score.pl?amount=100&token=AF32Z90

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

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

...