在深入具体的安全开发策略和防止作弊之前,理解 Roblox 安全的基础原则至关重要。一个安全的体验建立在预见对抗性行为的心态上。在编写任何代码之前,您必须内化这些基础原则。它们应影响您做出的每一个架构和设计决策。
永不信任客户端
这是基础原则。一个决心坚定的利用者对其本地状态和网络流量拥有完全的控制权。因为利用者拥有这种控制级别,任何依赖客户端执行的安全措施最终都会被绕过。这不是 Roblox 的局限性:这是客户端-服务器架构的基本现实。假设从客户端发送的每一条数据都已被篡改、伪造或以恶意意图发送。这包括以下能力:
- 反编译任何复制的 LocalScript 或任何 ModuleScript,即使它们从未在客户端运行
- 获取他们角色和任何未固定部件的网络所有权
- 在任何范围或频率上触发客户端启动的事件,例如 Touched 事件或 ProximityPrompt 激活
- 修改他们玩家的位置、物理行为或与世界的交互
- 以任意频率和任意参数(除了第一个 Player 参数)触发或调用 RemoteEvents 和 RemoteFunctions
- 在不触发任何预期事件的情况下更改其本地 DataModel 中的任何内容
- 任意更改任何本地运行代码的行为
因此,所有关键逻辑必须在服务器端进行验证或仅在服务器上运行。这种控制的后果在 网络所有权、移动验证和物理漏洞 和 访问控制和机密性 中有详细介绍。
服务器权威
服务器必须是所有模拟状态、规则、玩家进度和关键决策的最终真实来源。客户端的角色是呈现世界并将用户输入发送到服务器。
服务器的角色是:
- 接收来自客户端的输入
- 验证请求的操作是否可能和允许
- 执行操作并更新其权威状态
- 将结果复制给所有相关客户端
例如,如果玩家说“我想买一瓶 Bloxy Cola”,服务器必须知道该物品的真实价格、玩家的金钱和玩家角色与商店的物理距离,然后验证并批准交易。尽可能地,待验证的状态应仅由服务器维护,而不是由客户端维护。在这个例子中,如果 Bloxy Cola 交易被批准,服务器应该从玩家的金钱中扣除 Bloxy Cola 的价格,然而,服务器并不一定始终能控制玩家角色。
设计中考虑安全性
从一开始就将安全性考虑纳入您的体验设计中,而不是试图在事后将其附加上去。
- 对每个新功能进行威胁建模。对于每个新功能,询问:
- 如果攻击者完全控制他们的客户端,如何利用这一点?
- 如果客户端可以为功能使用的任何参数发送任何值,最坏的结果是什么?
- 如果每秒钟使用这一功能 1,000 次以上会发生什么?它应该被使用的最大频率是什么?
- 利用者是否可以利用这一点毁掉其他玩家的体验?
- 在最坏的情况下,这一功能可能消耗多少资源?
- 对于这一功能,我需要公开的最少内部信息或状态是什么?
- 及早划分职责。从第一天起就将逻辑和数据保留在 ServerScriptService 中。永远不要将它们放在像 ReplicatedStorage 或 Workspace 这样的复制容器中。