release

按下提交按钮之前 — 上线后难以回退的五个安全决定

「上线之后再加不行吗」— 大多数可以,除了这五项

对一支距离上线还有两周的团队提起安全,得到的回答大多是这样的:「现在内容收尾更急,先上线看看反馈再加。」

这是合理的判断。实际上,大多数安全功能确实可以之后再加。启用检测模块、收集日志、收紧策略,这些在长期运营中随时都能做。

问题在于,里面混着一些并非如此的东西。有几个决定在提交构建的那一刻就固化了,之后要改就得重新发版,或者动到玩家数据。该着急的是内容,这没错。只是这五项现在花三十分钟确认清楚,之后能省下几周。

本文不是一篇挑选「引入什么」的文章,只讨论现在不定下来、之后代价会变高的事。按团队规模决定从什么开始引入,另见面向独立与小型工作室的安全接入指南。

1. 脚本后端 — 用 Mono 发布了就不好回头

Unity 的脚本后端会改变构建产物本身的结构。用 Mono 构建,C# 代码会以托管程序集的形式留下,反编译器可以直接打开;IL2CPP 则会转换为原生二进制。

改动本身只是一个设置,但上线之后再改,麻烦才刚开始。构建时间和产物体积会变,原生插件、反射、序列化这些地方会冒出以前没有的问题。有余力在运营期间验证这些的团队并不多。

这不是说 IL2CPP 就万无一失。元数据仍会留下,还原工具能恢复相当一部分内容,详见IL2CPP 真的安全吗。这里想说的只有一点:用哪一种应当在上线前定好,并在该设置下完成验证。

2. 签名与包完整性 — 之后再动会动摇安装基础

应用签名与其说是安全设置,不如说更接近身份。签名变了,在商店和设备看来它就是另一个应用。

Android 如果使用 Play 应用签名,是有密钥升级路径的,但流程很重,而且可能影响已经安装的用户。上线前值得确认的大致是这些:

  • 签名密钥存放在哪里、谁可以访问,已经明确。
  • 构建流水线每次都使用同一把密钥签名。
  • 判断包是否被篡改的基准已经写进构建里。

第三项尤其不便于事后补上。要识别被重打包的构建,就得知道正规构建应该是什么状态,而这个基准是在构建时生成的。重打包攻击的流程在Unity MOD APK 防护指南中讲过。

3. 服务端判定的边界 — 改得最晚,代价也最高

五项中事后最难更改的一项。因为纠缠在一起的不是代码,而是数据结构与玩家记录。

上线前值得先回答的问题是:「这个数值一旦被操控,会不会影响其他玩家或收入?」

如果会,那么这个数值的最终判定就应当在服务端——货币余额、购买是否发放、排行榜分数之类。如果以客户端计算、服务端只做记录的结构上线,之后要转为服务端判定时,首先得决定已经累积的记录怎么处理。被操控的数值与正常数值,事后往往无法区分。

这并不是说要把一切都搬到服务端。单机内容的表现数值没有理由让服务端来判定。要点是在上线前决定这条线画在哪里。 存档侧的实例可参考游戏存档篡改。

4. 构建里残留的东西 — 提交前打开看一次

开发期间需要、但留在发布构建里就会出问题的东西。大多数团队都知道,却总在赶工期时漏掉。

  • 构建中没有残留开发或预发布服务器地址。
  • 测试账号、作弊指令、调试菜单入口已移除。
  • 调试符号与详细日志已按发布配置整理。
  • 包里没有打进未使用的开发用库。
  • 客户端中没有嵌入服务器 API 密钥或密文。

只有最后一项性质不同。前四项清理掉就算完成,但放进客户端的密文应当视为已经泄露。构建在用户设备上,其中的字符串最终会被读出来。发现了,需要的不是删除而是更换。

5. 检测之后做什么 — 没有策略,就会在运营中临时决定

启用检测,和依据检测结果采取行动,是两件事。而后者如果没有在上线前定好,就会在事故发生的凌晨临时决定。

需要定的有三点。

  • 要做什么 —— 只记录、警告,还是阻断。每个检测项可以不同。
  • 误报了怎么办 —— 正常玩家被判中时,有没有回退的通道。
  • 谁来判断 —— 自动处理与人工确认之间的边界。

在没有误报回退通道的情况下开启阻断,是实务中最危险的组合。错误拦下几个正常玩家,损失比放过几个作弊者更大。先只做记录,等数据积累后再提高强度,这个顺序才稳妥。

如果还在权衡接入方式本身,自研与商用 SDK 的比较可以作为参考。

提交前的最终检查

把上面五项集中成一次检查。

构建配置

  • 脚本后端已确定,并在该设置下完成了 QA。
  • 签名密钥的存放位置与访问权限已明确。
  • 判别包篡改的基准已包含在构建中。

结构

  • 被操控会影响其他玩家或收入的数值,最终判定在服务端。
  • 客户端判定与服务端判定的边界已形成文档。

构建残留

  • 开发服务器地址、测试账号、调试入口已移除。
  • 客户端中没有密文。若曾有,已完成更换。

运营准备

  • 每个检测项要做什么已经确定。
  • 存在回退误报的通道。
  • 团队已就「初期以记录为主」达成一致。

如果你正在评估 OZero Security

上述五项中,我们能帮上忙的是第 1、2 项的一部分以及第 5 项。Check Setup 会提示未使用 IL2CPP 的项目,并检查 Android 签名证书和 manifest 签名;检测之后的处理(日志、回调或退出)在 Response Settings 中设定。第 3、4 项属于游戏设计、服务端与发布流程的职责,我们无法代替。

只就接入负担补充一句:导入软件包后(Asset Store 购买的版本在 Package Manager 的 My Assets 中导入,客户门户下载的版本以 .unitypackage 导入)会打开 Welcome 窗口。Check Setup 列出项目尚缺的设置,Auto Setup 逐步确认后应用推荐设置,各模块在 Project Settings > OZero Security 中设置。不需要改场景或改游戏逻辑。即使临近上线才开始评估,负担也比第 1、2 项要小。

不过顺序还是建议遵守。脚本后端与签名体系先定下来,其上的完整性校验才有意义。

结论:把「之后能做的」和「现在必须定的」分开

把上线前的安全检查理解成「我们准备得够不够充分」,永远没有尽头。没有哪支团队是以完美状态上线的。

不如换个分法:之后能补的,和现在必须定的。本文的五项属于后者。其余的,等上线看过反馈再补也不迟。

下一步

  1. 确认防护范围 —— 查看各平台的支持规格,以及各方案(Standard / Pro)的防护范围。
  2. 快速开始接入 —— 导入与配置步骤见集成手册。
  3. 技术咨询 —— 如果上线排期紧张,可以咨询以当前配置能做到什么。

上线前该定下来的事 — OZero Security 通过导入包和 Check Setup 接入。

相关阅读