Companion 2017-03-09
最近不少 iOS 开发者都收到苹果的警告邮件,在邮件中,苹果称开发者使用了动态代码更新技术,要求开发者删除相关代码,并重新提交一个新的 App 版本以供审核。
邮件原文翻译如下:
尊敬的开发者,
您的应用,扩展程序和/或链接框架似乎包含明确设计的代码,能够在应用审核批准后更改应用的行为或功能,这不符合Apple开发人员计划许可协议和应用的第3.3.2节商店审查指南2.5.2。此代码与远程资源相结合,可以帮助对应用程序的行为进行重大更改,与最初对App Store进行审核相比。虽然当前可能不使用此功能,但它可能会加载私有框架,私有方法,并支持未来的功能更改。
这包括将任意参数传递给动态方法(如dlopen(),dlsym(),respondingToSelector :, performSelector :, method_exchangeImplementations())和运行远程脚本以便更改应用程序行为或调用API的任何代码,下载的脚本。即使远程资源不是故意恶意的,它也可能很容易被劫持通过中间人(MiTM)攻击,这可能对您的应用程序的用户造成严重的安全漏洞。
请对您的应用执行深入审核,并删除符合上述功能的任何代码,框架或SDK,然后再提交下一个更新以供审核。
而上文提到的苹果开发者协议3.3.2节具体内容如下:
一个应用程序不应该下载或安装任何可执行代码。解释执行的代码可以在应用内使用,如果所有的脚本、代码、和解释器都被打包在应用内而没有被下载。前述内容的唯一的例外在于下载的脚本和代码使用了Apple内置的WebKit框架或JavascriptCore,并且对应的脚本或代码并没有改变这个应用提供功能和特性的主要目的,与提交到AppStore的版本以及相应的宣传描述相符。
白鹭引擎的原生打包方案使用的就是JavascriptCore,所以对于使用白鹭引擎打包的原生游戏没有影响,请大家正常使用。
截止目前为止,我们也没有收到使用白鹭引擎打包游戏的开发者收到了苹果警告邮件的消息。
一句话总结:使用白鹭引擎并通过 Egret-iOS-Support 发布原生游戏,目前并不会收到影响。
以下内容为白鹭引擎架构师的个人观点,欢迎在技术层面进行讨论。
苹果是不是完全禁止了热更新技术?
并不是,目前为止收到警告邮件的开发者绝大部分使用了 JS-Patch 或 Rollout 类库,剩下未直接使用这些类库的开发者,目前初步估计很可能是在集成的第三方SDK 中使用了上述框架。而未采用上述框架的热更新技术,目前为止并未收到影响。而绝大部分游戏引擎由于并没有调用这些类库,也自然没有受到影响。
当然,后续事态会不会进一步扩大,还需要看苹果接下来的策略。但是笔者认为,游戏中的热更新技术并不会受到苹果的禁止,作为一名技术人员,我们不讨论产品、商业等问题,只从技术角度来看,为什么 JSPatch苹果认为是不允许的,而游戏引擎的热更新技术,苹果目前认为是可以的
苹果为什么要禁止 JSPatch 等热更新技术?
JSPatch 的原理是,开发者编写 JavaScript 代码,利用苹果内置的 JavaScriptCore.Framework 执行,以实现热更新功能。这一点看似也符合标准,但是在技术上,存在着重大安全隐患,参考 JSPatch 的业务逻辑:
require('UIView') var view = UIView.alloc().init() view.setBackgroundColor(require('UIColor').grayColor()) view.setAlpha(0.5)
简单理解,JSPatch可以理解为所有的 Objective-C 的 API 进行了映射,允许开发者在 JS 端调用任意原生代码。这显然是极其危险的。假设这段代码是通过热更新技术下载执行的,如果在中间存在黑客,把这段代码动态替换掉,比如修改为获取用户通讯录并上传到黑客的服务器,就会造成重大的安全问题。
为什么游戏热更新技术可以被理解为是安全的
与 JSPatch 不同的是,游戏热更新技术主要的实现方式是把动态脚本下载之后,让动态脚本调用游戏引擎提供的接口实现缺陷修复。与 JSPatch不同的是,动态脚本并不能任意调用全部原生代码,而是只能根据游戏引擎提供的接口调用相关功能。在这个过程中,游戏引擎的原生端作为一个安全沙箱,提供了一个安全的保护层,只要游戏引擎不要对外提供获取通讯录的接口,黑客就无法通过替换动态脚本的方式获取用户的隐私资料。进而可以被认为是安全的,自然不在苹果的禁止范围内。