作弊者滥用网络事件来给自己刷钱、生成载具和获取物品。本文讲解 FiveM 触发器漏洞的原理、为何难以人工审计,以及 ZeroTrust 的 Trigger Finder 如何映射并标记你的整个事件攻击面。
如果你经营 FiveM 服务器有一段时间了,一定遇到过这个问题:一名带作弊菜单的玩家在从不触碰预期界面的情况下,给自己刷钱、生成载具或把背包塞满物品。他并没有破坏游戏引擎,而是直接调用了你服务器的网络事件。
这是 FiveM 服务器被利用的最常见方式,而“保护好你的事件”是标准建议。问题在于,这条建议假定你已经知道哪些事件是暴露的。但在一台运行着数十个资源的服务器上,几乎没人知道。本文将解释触发器漏洞的原理、为何难以人工修复,以及我们如何把整个问题变成一个工具:Trigger Finder。
在 FiveM 中,脚本通过网络事件跨越客户端–服务器边界进行通信。客户端调用 TriggerServerEvent,服务器便运行为该事件名注册的处理函数。合法玩法正是这样运作的——而作弊正是滥用这一点。
作弊菜单可以用任意参数触发你服务器注册的任何网络事件。如果某个资源有一个会加钱、给物品或生成载具的服务器事件,并且它信任客户端发来的数值,作弊者只需直接调用它:
-- 存在漏洞:服务器信任客户端发送的一切
RegisterNetEvent("shop:buyItem", function(item, amount)
local ply = FX.GetPlayerFromSource(source)
-- 没有价格检查,没有校验 —— 一切由客户端控制
ply.addItem(item, amount)
end)
-- 作弊只需调用:
-- TriggerServerEvent("shop:buyItem", "gold_bar", 9999)修复单个事件的方法众所周知:在服务器端校验,绝不信任客户端输入。具体模式我们在 FiveM Lua 事件安全指南 中有详细说明。难点不在于修复一个事件,而在于知道它们全部都在哪里。
一台典型的 RP 服务器会运行 50 到 300+ 个资源,其中很多是你没写过的第三方脚本。每个都可能注册数十个网络事件——也就是可能有数千个事件,分散在你从未打开过的文件里。你无法保护看不见的东西,也没有人会为了找一个被遗漏的 addMoney 处理函数而手动通读每个资源。
我们没有再发布更多文档,而是把这项审计直接做进了 ZeroTrust 面板。思路很简单:如果服务器的危险之处在于它的事件面,那么每位所有者都应能一眼看到整个事件面,按风险排序,并能直达每一项。
Trigger Finder 是内置于 ZeroTrust 仪表板的扫描器。你发起一次由服务器触发的扫描,它会遍历你的资源并提取找到的每个事件和触发器——为每一项标注其资源、文件、行号、所在端(客户端或服务器)和事件名。
你不再靠猜测,而是得到一份完整、可搜索的清单,列出你服务器暴露的每个网络事件。每个触发器都记录了它所在的位置和流向——客户端 → 服务器、服务器 → 客户端、客户端 → 客户端 或 服务器 → 服务器——让你立刻看出哪些可被恶意客户端触及。
结果是一份覆盖整台服务器的风险分布:有多少触发器安全、多少危急,哪些资源含有最多危险事件,以及一切如何在客户端与服务器之间分布。
每条结果都链接回其 资源 → 文件 → 行,并提供代码上下文视图,让你就地阅读该触发器。当 Trigger Finder 标记出一个危险的 addItem 处理函数时,你会确切知道该加固哪个脚本、哪一行——无需翻找。
每台服务器都不同,尤其是使用自定义框架时。你可以配置自己的关键词和危险事件清单,让 Trigger Finder 标记对你的脚本而言重要的函数名,而不只是默认项。
Trigger Finder 告诉你该保护什么。下一步是堵上缺口:在服务器端校验每个被标记的事件,使用服务器端方法获取数值而非信任客户端,并在执行前检查玩家的状态、位置和权限。全部模式——以及值得启用的 FXServer 安全 convar——都在我们的 FiveM Lua 事件安全指南 中。
你无法防御一个从未见过的攻击面。Trigger Finder 把“保护好你的事件”这条含糊的建议,变成一份由你真实服务器生成的具体清单——让你确切知道什么被暴露、该在哪里修复。