5

假设在基于浏览器的游戏中,完成一些操作(为简单起见,假设某人点击了一个将他们的分数提高 100 的链接)点击这个链接,该链接将有一个 url,例如increase_score.pl?amount=100,某人简单地发送了什么样的预防措施请求 Web 服务器执行此命令:

  1. 一遍又一遍地没有真正完成点击链接的任务
  2. 向服务器发送虚假请求,其中数量设置为 100000 之类的 rediculus。

我知道检查,HTTP_REFERER但是我知道人们可以解决这个问题(不确定如何准确),除了检查第二个选项的一些边界之外,我有点难过。有人遇到过类似的问题吗?解决方案?

4

10 回答 10

15

如果您按照您的建议实施您的游戏,没有什么可以阻止他们这样做。

您需要在服务器上实现游戏逻辑并仅在服务器验证操作后分配积分。

例如:当有人投票支持您的问题时,这不会作为增加您的声誉的命令发送。该网络应用程序只是对服务器用户 X 对问题 Y 投了赞成票。然后,服务器验证数据并在一切检查完毕后分配分数。(不是说 SO 是游戏,但需要的逻辑是类似的。)

于 2009-11-16T21:13:11.463 回答
5

简短版:你不能。您从客户端(浏览器)获得的每一条数据都可能被知道自己在做什么的人手动欺骗。

您需要从根本上重新考虑应用程序的结构。您需要对应用程序的服务器端进行编码,使其将来自客户端的每条数据都视为一堆肮脏的谎言,直到它可以向自己证明数据实际上是合理的。您需要避免给服务器一种“如果客户端告诉我这样做,显然它被允许告诉我这样做”的心态。

错误的方式:
客户:玩家史蒂夫说要给玩家史蒂夫一亿分。
服务器:好的!

正确方法:
客户:玩家史蒂夫说要给玩家史蒂夫一亿分。
服务员:好吧,让我先看看玩家史蒂夫是否允许在这个时候给自己一个亿万分……啊。他不是。请向玩家史蒂夫显示此“Go Fsck Yourself, Cheater”消息。

至于告诉谁登录,这很简单,只需将一个 cookie 交给客户端,该 cookie 的值您在服务器上跟踪,该值几乎不可能猜到——但我假设您知道如何处理与会话管理。:-) (如果你不这样做,谷歌会等待。

于 2009-11-16T21:27:32.587 回答
3

游戏(应用程序)的逻辑应该基于不信任来自用户的任何东西的规则。

HTTP_REFERER 可以被任何 Web 客户端欺骗。

于 2009-11-16T21:16:22.657 回答
1

带有 cookie/会话的令牌。

于 2009-11-16T21:12:28.530 回答
1

您可以使链接动态化,并在其末尾更改散列。在给定的时间段内验证哈希是否正确。

这取决于您允许点击的频率,其复杂性会有所不同。

于 2009-11-16T21:16:11.503 回答
1

这里有几点需要注意。

首先,您的服务器对此类内容的请求应该是 POST,而不是 GET。只有 GET 请求应该是幂等的,不这样做实际上违反了 HTTP 规范

其次,您在这里看到的是经典的客户信任问题。您必须信任客户端将分数或其他游戏间隔信息发送到服务器,但您希望客户端发送非法数据。防止不允许的操作很容易 - 但在允许的操作中防止犯规数据的问题要大得多。

Ben S 对如何设计客户端和服务器之间的通信协议提出了一个很好的观点。允许将点值作为可信数据发送通常是个坏主意。最好表明发生了一个动作,并让服务器计算应该分配多少点,如果有的话。但有时你无法解决这个问题。考虑一个赛车游戏的场景。客户端必须发送用户的时间,并且不能将其抽象为诸如“completedLevelFour”之类的其他调用。那你现在怎么办?

Ahmet 和 Dean 建议的令牌方法是合理的 - 但它并不完美。首先,令牌仍然必须传输到客户端,这意味着它可以被潜在的攻击者发现并被恶意使用。另外,如果你的游戏 API 需要是无状态的怎么办?这意味着基于会话的令牌身份验证已过时。现在你进入了客户信任问题的深层、黑暗的肠子。

您几乎无法做到 100% 万无一失。但是你可以让作弊变得非常不方便。考虑 Facebook 的安全模型(每个 API 请求都经过签名)。这非常好,并且需要攻击者真正深入研究您的客户端代码,然后才能弄清楚如何欺骗请求。

另一种方法是服务器重放。就像赛车游戏一样,不仅仅是将“时间”值发送到服务器,还具有记录时间并将其全部发送的检查点。为每个间隔建立现实的最小值,并在服务器上验证所有这些数据都在既定范围内。

祝你好运!

于 2009-11-16T21:40:01.693 回答
1

听起来您的游戏的一个组件需要请求限制。基本上,您跟踪特定客户访问您网站的速度,当他们的速度超过您认为合理的速度时,您开始放慢对该客户的响应。有各种级别,从低级 IP 过滤器到您在 Web 服务器中处理的内容。例如,Stackoverflow 在 Web 应用程序中有一点可以捕捉到它认为太多的编辑太靠近了。如果您想继续,它会将您重定向到您需要回复的验证码。

至于其他位,您不仅要验证所有输入的形式(例如,它是一个数字),还要验证该值是否合理(例如,小于 100 或其他)。如果您发现客户在做一些有趣的事情,请记住这一点。如果您发现同一个客户经常做一些有趣的事情,您可以禁止该客户。

于 2009-11-16T22:27:27.727 回答
0

扩展 Ahmet 的响应,每次加载页面时,都会生成一个随机密钥。将密钥存储在用户会话中。将随机密钥添加到每个链接,以便获得这 100 分的新链接是:

increase_score.pl?amount=100&token=AF32Z90

单击每个链接时,检查以确保令牌与会话中的令牌匹配,然后创建一个新密钥并将其存储在会话中。每次他们提出请求时都会有一个新的随机密钥。

如果他们给你错误的键,他们正在尝试重新加载页面。

于 2009-11-16T21:16:45.713 回答
0

我建议为每个操作创建一个特定的 URL。类似于以下内容:

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

这些链接中的每一个都可以做两件事:

  1. 在会话中标记该链接已被单击,以便它不会再次跟踪该链接。
  2. 添加到他们的分数。
于 2009-11-16T21:17:29.253 回答
0

如果您希望游戏仅在您的服务器上运行,您还可以在接收技巧中检测信号的发送位置,并忽略任何不是来自您的域的内容。如果您必须从您的专用域运行以提交分数,那么篡改您的代码将是一件非常痛苦的事情。

这也阻止了 CheatEngine 的大部分技巧。

于 2011-07-15T22:27:44.003 回答