有什么好方法可以防止JavaScript多人游戏中的作弊行为?

问题描述 投票:31回答:8

想象一下具有滚动水平的太空射击游戏。 有什么方法可以阻止恶意玩家修改游戏以使其受益? 他能做的事情很难限制服务器端是自动瞄准,在可见区域外窥视,加速黑客攻击和其他事情。

有什么方法可以防止这种情况发生? 假设服务器是任何语言,并且客户端通过WebSocket连接。

始终假设代码是100%可攻击的。 想办法防止客户完全重写(为了作弊)欺骗。 这些可以是诸如编写安全游戏协议的方法,服务器端检测等。

javascript security multiplayer
8个回答
36
投票

服务器是王道。 客户是可以破解的。

您想要做的是使用websocket做两件事。

将游戏操作发送到服务器并从服务器接收游戏状态。

您渲染游戏状态。 并将输入发送到服务器。

  • 自动瞄准 - 这个很难解决。 你必须追求现实主义。 如果用户在10ms内击中10次爆头,那么你就踢他了。 写一个聪明的作弊检测算法。
  • 在可见区域外偷看 - 只通过向每个客户发送可见区域来解决
  • 加速黑客攻击 - 通过正确处理输入解决。 您收到一个事件,用户向前移动并控制他的速度。

你解决不了的涅槃代码这些问题。 客户端上的代码用于处理输入和显示输出。 所有逻辑都必须在服务器上完成。

您只需编写服务器端验证 。 唯一的事情是游戏输入由于复杂性而难以验证然后形成输入。 这与使表单安全的方式完全相同。

你需要非常小心你的“输入有效”检测。 你不想踢/禁止游戏中的高技能玩家。 很难达到机器人检测过于宽松和机器人检测过于严格的平衡。 整个机器人检测领域非常困难。 例如,Quake有一个自动目标检测功能,可以在当天恢复熟练的熟练玩家。

至于停止机器人连接到您的websocket,直接在您的多人游戏中设置单独的HTTP或HTTPS验证通道,以增加安全性。 使用多个Http / https / ws通道将客户端验证为“官方”,充当某种形式的握手。 这将使得与ws的连接更加困难。

例:

想想一个简单的多人游戏。 基于2D房间的赛车游戏。 最多n个用户使用平面2D平台地图并竞赛从A到B.

让我们假设您有一个傻瓜系统,其中有一个复杂的验证通过HTTPS通道,以便用户无法直接访问您的websocket频道,并被迫通过浏览器。 您可能有一个处理身份验证的Chrome扩展程序,并强制用户使用它。 这减少了问题域。

您的服务器将发送客户端呈现屏幕所需的所有可视数据。 你无法掩盖这些数据。 无论你尝试什么,一个愚蠢的黑客都可以把你的代码放慢,然后在调试器里慢慢编辑它,直到他所有的东西都是你的websocket的原始包装器。 他让你运行整个身份验证,但没有什么可以阻止他删除你写的任何JavaScript,阻止他这样做。 你所能达到的只是限制了黑客熟练访问你的websocket的数量。

所以黑客现在将你的websocket放在一个镀铬沙盒中。 他看到了输入。 当然,您的赛道是动态且独特的。 如果你有一定数量的黑客,那么黑客可以预先设计出最佳的竞赛路线。 您发送的可视化此地图的数据可以更快地呈现,然后人工与您的游戏互动,并且可以计算出赢得您的赛车游戏的最佳动作并发送到您的服务器。

如果你试图禁止那些对你的地图数据反应太快的玩家并称他们为机器人,那么黑客会调整这个并增加延迟。 如果你试图禁止那些玩得太完美的玩家,那么黑客就会调整这个并使用随机数来减少玩法。 如果您在地图中放置陷阱,只有算法机器人会陷入困境,那么可以通过试验,错误或机器学习算法来了解陷阱。 没有什么可以做到绝对安全。

你只有一个绝对避免黑客的选择。 那就是建立自己的浏览器,不能被黑客攻击。 在浏览器中构建安全机制。 不允许用户在运行时实时编辑javascript。


3
投票

在服务器端,有两个选项:

1)完整的服务器端游戏

每个客户端将其“操作”发送到服务器。 服务器执行它们并发回相关数据。 例如,船舶想要向北移动,服务器计算其新位置并将其发回。 服务器还发送可见船只列表(解决maphacks)等。

2)完整的客户端游戏

每个客户端仍然将其操作发送到服务器。 但是为了减少服务器上的工作负载,服务器不会执行操作,而是将它们转发给所有其他客户端。 然后客户端同时解决所有操作。 结果,每个客户端应该以相同的游戏结束。 每个客户端定期将其绝对数据(发货位置等)发送到服务器,服务器检查所有客户端数据是否相同。 否则,游戏不同步,有人必须是黑客。

第二种方法的缺点是某些黑客仍然未被发现:例如,一个maphack。 骗子可以注入代码,以便他看到所有内容,但仍然只发送他通常能够看到的数据到服务器。

-

在客户端,有一个选项:一个ja​​vascript组件,它扫描游戏代码以查看是否有任何内容被修改(例如,代码被修改为呈现不可见的对象但向服务器发送不同的验证数据)。

显然,黑客可以轻松禁用此组件。 要解决此问题,您可以强制客户端定期从服务器重新加载组件(服务器可以检查用户是否定期请求脚本文件)。 这引入了一个新问题:黑客只是通过AJAX定期请求组件,但阻止它运行。 为了避免这种情况:让组件重新下载,但稍微修改一下。

例如:让组件位于yoursite / cheatdetect.js?control = 5。 服务器将生成一个稍微修改过的cheatdetect.js,以便在下一次迭代中,必须下载cheatdetect.js?control = 22(例如)。 如果控制机制足够复杂,则黑客将无法预测接下来请求哪个控制号,并且必须执行cheatdetect.js才能继续游戏。


3
投票

尽可能地模糊您的客户端公开代码。 另外,使用一些魔法。


1
投票

你无法阻止任何人修改你的JS或编写GreaseMonkey脚本。 但是,通过缩小脚本以及使代码尽可能神秘,您可以使它们变得困难。 甚至可能会抛出一些虚假的方法或变量,这些方法或变量什么都不做,但却被用来抛弃攻击者。 但是如果有足够的时间,这些方法都不是完全万无一失的,因为一旦你的代码进入客户端,它就不再是你的了。


1
投票

他们不必触摸您的客户端代码 - 他们可以只是嗅探并实现您的Websocket协议并编写一个假装成人类玩家的小代理。

更新:问题有几个部分,我没有最高层的答案,但可以考虑这些问题来评估各种选项:

  1. 你愿意在多大程度上防止作弊? 如果你只关心随意作弊,那么有多少障碍足以阻止休闲作弊者? 中级Javascript程序员? 一位认真的专家? 权衡这种欺骗的好处,是否有任何真正的价值,如现金和奖品,或只是声誉?
  2. 你如何高度确信人类正在为你的游戏提供输入? 例如,有了足够好的计算机视觉库,我可以在一台单独的机器上为游戏建模,假装是鼠标的计算机输入,但这相对成本较高(不值得我花时间)。
  3. 如何在协议中创建信任链,以便将(2)的知识传递给服务器,并且您的服务器相对确信您的客户端代码正在发送消息?

当然,你抛出的许多障碍都可能是侧面的,但玩家和你的成本是多少? 见“ 消耗战 ”。


1
投票

我甚至可以想到实现这一点的唯一方法是修改您的Javascript以充当客户端,然后设计中央服务器机制来验证从该客户端发送的数据。 这可能是实施的一个重大变化,很可能会使您的项目更加复杂。 但是,如前所述,如果应用程序完全在客户端上运行,则客户端可以使用您的脚本执行任何他们想要的操作。 保护它使用受信任的机器来处理验证的唯一方法。


0
投票

您可以在浏览器上编辑javascript并使其正常工作。 有人建议拨打电话查询服务器。 因此,在调用服务器后,它将在服务器中进行验证。 一旦经过验证,它将进入客户端并执行操作。 但我认为即使这不是万无一失的。

例如,。 对于基本登录操作:在对服务器进行调用时的角度,后端验证用户名和密码,如果验证,它将返回到客户端并让用户使用angular登录。

当我说使用angular登录时,它会将内容存储在cookie中,比如用户对象和其他东西。 但是用户仍然可以删除正在调用后端的JS代码,并返回TRUE(在需要的地方)并将用户对象(虚拟)插入到cookie和其他对象(无论需要什么)和登录。 这是一件非常困难的事情,但它是可行的。 在许多情况下,即使编辑/破解代码需要数小时,这也是不可取的。

这在单页面应用程序中是可能的,其中JS文件不会为每个页面重新加载。 为了减少被黑客攻击的可能性,我们可以使用缩小的代码。 我想如果这样的动作是在后端完成的(比如在Django中登录),那就更安全了。

如果我错了,请纠正我。


0
投票

我会使用缩小和AJAX的组合。 如果所有的功能和数据都没有加载到页面中,那么作弊就更难了。

另一方面,modding对像Id Software这样的公司来说是一个非常有利可图的工具。 也许允许对系统进行修改可能会使整个社区的游戏更加愉快。

© www.soinside.com 2019 - 2024. All rights reserved.