让我们说在基于浏览器的游戏中,完成一些操作(为简单起见,可以说有人点击了一个增加了100分的链接)点击此链接会有一个网址,例如increase_score.pl?amount=100
是什么类型的有人只是简单地向Web服务器发送请求以执行此命令:
我知道检查HTTP_REFERER
然而我知道人们可以解决这个问题(不确定究竟如何),除了检查第二个选项的某些界限之外我有点难过。有人遇到过类似的问题吗?溶液
答案 0 :(得分:15)
如果你按照你的建议实施游戏,没有什么能阻止他们这样做。
您需要在服务器上实现游戏逻辑,并且只有在服务器验证操作后才分配点。
例如:当有人对您的问题进行投票时,这不会作为增加您声誉的命令发送。网络应用程序只是对服务器用户X说投票问题Y。然后,服务器验证数据并在所有内容都检出时分配点数。 (不是说SO是游戏,但所需的逻辑是相似的。)
答案 1 :(得分:5)
简短版:你不能。您从客户端(浏览器)获得的每一条数据都可以由知道他们正在做什么的人手动欺骗。
您需要从根本上重新思考应用程序的结构。您需要对应用程序的服务器端进行编码,使其将来自客户端的每个数据视为一堆肮脏的谎言,直到它可以证明数据实际上是合理的。你需要避免给服务器一个心态“如果客户告诉我这样做,显然允许告诉我这样做。”
错误的方式:
客户:球员史蒂夫说要给球员史蒂夫一个巨大的积分
服务器:好的!
正确的方式:
客户:球员史蒂夫说要给球员史蒂夫一个巨大的积分
服务器:好吧,让我首先检查一下,在这个时刻玩家史蒂夫是否允许给自己一个巨大的积分......啊。他不是。请向玩家史蒂夫显示“Go Fsck Yourself,Cheater”消息。
至于告诉谁登录,这是一个简单的问题,即将客户端的cookie与你在服务器上跟踪的几乎无法猜测的值相提并论 - 但我会假设你知道如何处理会话管理。 :-)(如果你不这样做,Google awaits.)
答案 2 :(得分:3)
游戏(应用程序)的逻辑应基于不信任来自用户的任何规则的规则。
任何网络客户端都可以欺骗HTTP_REFERER。
答案 3 :(得分:1)
使用cookie / session进行令牌。
答案 4 :(得分:1)
您可以使链接动态化,并在其末尾更改哈希值。在这段时间内验证散列是否正确。
根据您允许点击的频率,这会有很大的复杂性。
答案 5 :(得分:1)
这里有几点需要注意。
首先,你的服务器请求这样的东西应该是POST,而不是GET。只有GET请求应该是幂等的,而不是这样做实际上是a violation of the HTTP specification。
其次,您在这里看到的是经典的客户信任问题。您有信任客户端将分数或其他游戏间隔信息发送到服务器,但您不希望客户端发送非法数据。防止不允许的操作很容易 - 但是在允许的操作中防止犯规数据更容易出问题。
Ben S对如何在客户端和服务器之间设计通信协议提出了一个很好的观点。允许将点值作为可信数据发送通常是个坏主意。最好指出发生了一个动作,并让服务器确定应该分配多少点,如果有的话。但有时你无法解决这个问题。考虑赛车游戏的场景。客户端具有来发送用户的时间,并且不能将其抽象为其他一些调用,例如“completedLevelFour”。那么你现在做什么?
Ahmet和Dean建议的令牌方法是合理的 - 但它并不完美。首先,令牌仍然必须传输到客户端,这意味着它可以被潜在的攻击者发现并且可以被恶意使用。此外,如果您的游戏API需要无状态怎么办?这意味着基于会话的令牌认证已经完成。现在你进入了客户信任问题的深层,黑暗的内容。
你几乎无法做到100%万无一失。但你可以让它非常不方便作弊。考虑Facebook的安全模型(每个API请求都已签名)。这非常好,并且要求攻击者在他们弄清楚如何欺骗请求之前实际挖掘客户端代码。
另一种方法是服务器重播。就像赛车游戏一样,不仅要将“时间”值发送到服务器,还要有记录时间并将其全部发送的检查点。为每个间隔建立实际的最小值,并在服务器上验证所有这些数据都在建立的范围内。
祝你好运!答案 6 :(得分:1)
听起来你的游戏的一个组成部分需要请求限制。基本上,您会跟踪特定客户访问您网站的速度,当您的费率超出您认为的合理范围时,您就会开始减慢对该客户的响应速度。从低级IP过滤器开始,直到您在Web服务器中处理的内容,有各种级别。例如,Stackoverflow在Web应用程序中有一点点可以捕获它认为太多编辑太接近的内容。如果您想继续,它会将您重定向到需要响应的验证码。
对于其他位,您应该验证所有输入不仅仅是因为它的形式(例如它是一个数字),而且还要验证该值是否合理(例如小于100,或者其他)。如果你抓住一个客户做一些有趣的事情,请记住。如果你经常抓住同一个客户做一些有趣的事情,你可以禁止那个客户。
答案 7 :(得分:0)
扩展Ahmet的响应,每次加载页面时,都会生成一个随机密钥。将密钥存储在用户会话中。将随机密钥添加到每个链接,以便获得这100个点的新链接是:
increase_score.pl?amount=100&token=AF32Z90
单击每个链接时,请检查以确保令牌与会话中的令牌匹配,然后创建新密钥并将其存储在会话中。每次发出请求时都会有一个新的随机密钥。
如果他们给你错误的密钥,他们就会尝试重新加载页面。
答案 8 :(得分:0)
我建议制作一个特定于每个操作的网址。有点像:
/score/link_88_clicked/
/score/link_69_clicked/
/score/link_42_clicked/
这些链接中的每一个都可以做两件事:
答案 9 :(得分:0)
如果您希望游戏仅在您的服务器上运行,您还可以在接收技巧中检测信号的发送位置,并忽略不属于您的域的任何内容。如果您必须从专用域运行以提交分数,那么篡改您的代码将是一个真正的痛苦。
这也阻止了CheatEngine的大部分技巧。