关于苹果警告

2017-3-9

昨天早上 iOS 开发者们陆续收到苹果邮件,警告去掉动态下发功能,覆盖面很广,内容没有明确指示是什么库,导致大家各种猜测。

其实上周已经有少量用户收到苹果这份警告邮件,当时还以为是特例,现在看来是在灰度测试扫描代码,可见这事苹果应该讨论已久,并专门排期开发测试了扫描程序,直到昨天才正式上线。

从各方信息看起来,很不幸主要禁的还是 JSPatch / wax/ rollout 这样的热修复框架,特点是可以通过 JS 脚本调用和替换任意 OC 方法,而像 React Native/ 小程序这样用 JS 做功能的暂时不受影响,Weex 不确定,至于其他库像 AFNetworking / SDWebimage 用到那几个接口的,应该只是误伤。

根据苹果要求,收到警告的同学只需要在下次提交版本时去掉相关框架就可以,没有时间期限,目前也不会强制下架。

为什么

苹果为什么这么做呢?苹果对热修复一直以来的态度都是不赞同也不拒绝,JSPatch 本身也并没有违反开发者条例,而且 JSPatch 大多数都用于修复 bug,提升 iOS 平台 App 的质量,对苹果也是件好事,为什么要禁?猜测原因有两点:可控和安全。

可控

苹果一贯作风是让所有事情可控,开发者能用什么不能用什么都尽量在自己的控制范围内。大多数人使用 JSPatch 修复 bug,或者弄一些临时运营的小功能配置,这些没有问题,但总会有少数用户使用 JSPatch 去调用私有API做些事,这是苹果不可控的,也无法知道有多少人这样做了。

不过其实在代码这块苹果其实一直可控程度有限,他会在提交时扫描你有没有用某些私有方法,但只要你对这些私有方法调用做一些变化,加解密字符串拼接什么的,就能绕过扫描,再通过后台配置调用,是一样的。JSPatch 只是让调用私有 API 变得成本更低更方便点而已,可控这里只是个小理由。

安全

去年 FireEye 分析了使用 JSPatch 的安全问题,当时我也写文章回应了,再复述一下,主要安全风险有三点:

  1. 开发者自己本身对 APP 下发恶意代码。
  2. 开发者没有做好加密传输和校验。
  3. 开发者接入的SDK里接入了JSPatch,SDK 作者可以对这些 APP 下发恶意脚本。

第一点其实不算安全风险,因为开发者自己有恶意的话完全不需要借助 JSPatch。

第二点大多数用户使用 JSPatch 时都做好了非对称加密,保证不会在传输过程被第三方篡改。但这里技术上没法保证用户一定使用正确的加密方式,苹果无法知道有多少接入 JSPatch 的用户没有正确加密和校验,这是未知的安全隐患。

第三点在当时并没有什么第三方 SDK 接入 JSPatch,但现在像高德地图/个推等都接入了,如果他们要作恶,或者他们本身服务端被入侵,确实是个安全隐患。

iOS 平台是最安全的,也是最注重安全的,即使热修复带来了 App 质量更高的好处,也无法无视这里的安全隐患,现在 JSPatch 国内覆盖面很大,若出一个安全问题,会影响 iPhone 的声誉,因为这个风险,所以考虑禁掉。

反应

这个警告出来后,国内开发者有各种反应,各种表情贴图还挺搞笑的,不过大家放心,JS没事,iOS 开发该失业的还是失业:)

看到有一些人拍手称赞,赞的理由不是说苹果维护了平台安全,而是:1.国内开发方式low,2.产品经理滥用。这里我有一些想法说一下。

开发方式

他们说国外开发不理解国内为什么要用热修复,国外很少使用,国外开发流程很好很规范,会做好充分的 codereview 和测试,上线后没什么 bug,不需要热修复,也不会有产品经理乱提需求,迭代没像国内这么快,使用热修复是本末倒置,不去考虑提高 APP 质量,国内开发方式太 low,国外的才是正道。

这里有个问题,就是什么是好的开发方式?以什么标准界定?上面的说法可以看出他们是把工程的严谨性,流程的规范性作为好坏的依据。虽然我是个程序员,觉得工程严谨和流程规范确实是好东西,但我比较实用主义,更倾向于以结果作为标准,也就是能不能更低成本更高效地开发出质量更好的产品作为标准。

如果我使用热修复能以更低的人力成本(工程师能力和薪水不如国外,人数少),更高效(测试时间缩短,不需要覆盖到0.01%几率出现的 bug / crash ),做出质量更高的产品( bug / 特殊情况和需求反应速度快),为什么不是一个更好的开发方式呢?

另外客户端的开发方式本身就是落后的,不利于快速迭代,无法对线上产品有控制权,参考另一篇文章。这也就是为什么 Facebook 一开始要用 web hybird 的方式开发,现在又要做 React Native。热修复是这种落后开发方式的弥补。另外我没在国外公司工作过,但感觉他们对bug的容忍程度还是比国内高的,对比一下 IAP 和微信支付的失败率,做过的人都知道。

还有一个声音说国内的人喜欢违反规则,钻空子太不老实。首先前面也说了热修复的方式并没有违反规则,完全符合开发者条例,其次国外也有热修复 rollout,最后如果从开发者条例来说,React Native 反而是违反规则的,因为主要用途动态添加和修改 APP 的功能。

滥用

另一个说法是上了热修复后产品经理来劲了,产品时不时想到一个功能配置说上就上,开发者弱势只能跟着上。

这种情况在我这边团队还没遇到过,我的想法是:如果要上的功能配置对产品是有好处有必要的,开发维护成本又低,为什么不上?如果要上的功能配置是无关紧要的,或者开发维护成本太高,为什么不能讲理拒绝?

开发者把原因定位为自己“弱势”,就把自己从团队剥离开了,变成对人不对事,这种团队氛围是挺糟糕的,而这个锅也不是产品经理的。大家做的事都是为了产品更好,应该不会有那么多故意刁难不讲理的产品经理和老板。至于怎样界定对产品有没有好处和有没有必要,以及开发成本高低,这得自己协商了,以我们团队的做法是以做这个事的性价比计算。

怎么办

接下来如果还想用 JSPatch 怎么办?我没有跟苹果审核团队交流过,不知道他们的想法,短时间内是先不要用,后续再看情况。

热修复的需求很大,很希望苹果可以推出自己的方案,由系统做这个事是可以保证安全的,但现在看起来可能性较低,国外需求量不大,苹果也就不会重视这个需求,何况目前在大力推 Swift。

对于 JSPatch,苹果应该是扫描可执行文件里的关键字,从技术上说是很难禁掉的,可以做各种混淆去绕过检查,但若下发时被查到,会有政策风险,政策有待观察。

实际上动态化还是处于灰色地带,严格来说 RN 是不符合规则的,但还是被允许,只要不给苹果添麻烦,苹果就不会管,JSPatch 因为上面提到的两点风险被管了,怎样做到使用并不给苹果添麻烦呢?

  1. 减少自行接入的使用人数。
  2. 禁止 SDK 接入。
  3. 接入保证传输安全和只用于修复 bug。

第一点警告邮件和代码检查使得自行接入 JSPatch 门槛变高了,显然会减少使用人数。第二点第三点只要有一个平台来管控,由平台保证安全性以及扫描下发的脚本,禁止私有API调用,禁止大量脚本下发,是可以做到的,可能的话希望能跟苹果审核团队协商。

附上 JSPatch 平台初定的解决方案

分类:互联网
评论

2017年3月9日 11:52

1 让自己的APP少点用户?
2 JSPatch是开源的,代码你可以自己修改,问题一样被警告.
3 这个就见仁见智了,你说时修BUG,APPLE会信吗?

2017年3月9日 11:56

@decwang
1. 是接入的APP少点
2. 若有平台控制,不允许自行接入,可以控制不准SDK接入
3. 若有平台控制,可以像苹果一样扫描脚本是否有私有API调用

2017年3月9日 12:00

那集成SD和AF库的App还能审核过么?

2017年3月9日 12:06

持续关注

2017年3月9日 12:11

没啥好说的,热修复对于一些小公司,测试人手不足时修复一些小bug非常有用
希望苹果能有自己的热修复机制吧

2017年3月9日 12:27

@bang
对程序员和产品来说,修BUG是个强需求,只要你的平台可用,人们会一窝蜂一样涌过来的.

2017年3月9日 13:08

@decwang 你说得也对,第一点应该改为减少自行接入的人数,有平台控制的用户保证安全和不滥用,人数多也不是问题。

2017年3月9日 13:16

不知道是否跑题@bang,如果这几天有人收到 Apple 的警告,并且提交了审核,希望分享一下审核的结果

2017年3月9日 13:48

在 iOS 这样一个平台上,当一项新技术各大厂商、开发者皆来参与时,苹果势必会监管。但堵死不会,所以我们下一步需要的就是平台管控,即为治本。只是这过程中,成本太高,时间太长,所以当下有何治标之策呢?

2017年3月9日 13:52

而『看到有一些人拍手称赞,赞的理由不是说苹果维护了平台安全,而是:1.国内开发方式low,2.产品经理滥用。』,其实王健林之前演讲中有一段话说得很对,具体可看:http://mp.weixin.qq.com/s/5hCblywnaSjqC936INabwA

2017年3月9日 14:05

iOS 这边禁掉没啥可说的,关键是 android 可以热更呀~这样以来,开发 iOS 的成本更高了。希望苹果能重视这方面的需求,搞一个官方的解决方案出来。

2017年3月9日 14:09

『JS没事,iOS 开发该失业的还是失业』,说的太对了。

2017年3月9日 14:10

支持bang哥!

2017年3月9日 14:25

同样希望国内的 app 增加质量,而不是增加各种功能。

2017年3月9日 15:22

facebook app里并没有使用RN,他们只是将RN用在了极个别小app内。facebook吃过hybird的亏,所以他们现在非常尊崇native开发。这是你首先要了解的情况。

2017年3月9日 15:25

@chentoo 是因为性能和体验优先才尊崇native开发,而不是开发方式,另一篇文章里也说过了。

2017年3月9日 15:24

微软这个low货,竟然开发了codepush热更新插件。

2017年3月9日 15:55

邦哥,挺住!你用JSPatch 改写了苹果的审核历史,让世界向前进了一步,无论是安全还是机制,都会推动苹果去思考怎么适应这么大的动态修复需求!!!

2017年3月9日 16:03

很喜欢JSPatch里面OC端到JS端方法和参数的调用方式,比原生的好用太多
能不能出个阉割版的?我的APP没有用到热部署功能,用的JS来写业务逻辑。

2017年3月9日 19:52

总结的到位,我们三天前提交的一版纯原生的IOS应用,目前还是在审核中的状态,如果苹果效率能够再提高一点,谁想那么麻烦用热修复呢,苹果更应该从自身来找问题

2017年3月9日 19:58

关于同样存在风险的RN和Code-Push,我猜是因为苹果不敢对Facebook和微软这样的大公司下手,真那么干很有可能要吃官司的

[…] JSPatch 的作者寫了一篇公告:关于苹果警告,勸大家先不要用避個風頭。也表達希望如果可以 Apple […]

2017年3月10日 10:35

1、安全、可控是最大的因素,没什么问题。
2、审核速度没有慢到要背锅的程度吧。

2017年3月10日 14:04

审核已经被拒了

2017年3月10日 15:08

『JS没事,iOS 开发该失业的还是失业』,呵呵,大牛就是大牛。

2017年3月13日 13:31

ReactNative&&weex&&小程序,他们对于原生API的调用是有限的,JSPatch、wax、rollout 并没有API的限制 ,这篇文章结尾处说的很对http://geek.csdn.net/news/detail/185602

[…] 关于苹果警告 […]

2017年3月20日 15:47

支持bang哥!我觉得JSPatch挺有价值,虽然没用JSPatch,但也是被Performance – 2.5.2这一条给打下来了,最后把项目里面用到method_exchangeImplementations 的代码注释掉,最后能正常上架。

2017年3月22日 10:39

头一次看Alert这种东西拿Web前端写还得写一大套组件的玩意儿。 就这么麻烦的东西也配说iOS能失业?失业的总是没有基本功不扎实的,jser浮躁的态度拿框架疯狂吹nb的本质还是不变的。

2017年3月22日 10:49

JS这种东西坑多的东西“熟练”jser早就当做“丰富的经验”都hold 住了。
然而好用的东西应该一上来就好用而不是要“丰富的经验”。
JSPatch算不上好的“开发方式”,一不小心写了个全局变量bug都不好查,哪管换个有类型语言做这个也行。
至于low b的iOS开发,清一色strong ARC丝毫不了解、API制定渣渣、设计模式不会用、mach底层不了解之流你让他写别的该失业也失业。

2017年3月22日 10:58

最后一条评论,我想反驳只有{开发方式}一栏,没有说JSPatch存在的意义不重要,只是觉得“开发方式”换做“存在意义/更多赋能”才能正确做大众的导向。

2017年3月22日 17:49

@AntiMoron 。。你缺乏幽默感

2017年3月29日 18:29

我好像看到有人叫我

2017年5月10日 9:24

不行了, 今早被拒了

Guideline 2.5.2 – Performance

Your app, extension, or linked framework appears to contain code designed explicitly with the capability to change your app’s behavior or functionality after App Review approval, which is not in compliance with App Store Review Guideline 2.5.2 and section 3.3.2 of the Apple Developer Program License Agreement.

This code, combined with a remote resource, can facilitate significant changes to your app’s behavior compared to when it was initially reviewed for the App Store. While you may not be using this functionality currently, it has the potential to load private frameworks, private methods, and enable future feature changes. This includes any code which passes arbitrary parameters to dynamic methods such as dlopen(), dlsym(), respondsToSelector:, performSelector:, method_exchangeImplementations(), and running remote scripts in order to change app behavior and/or call SPI, based on the contents of the downloaded script. Even if the remote resource is not intentionally malicious, it could easily be hijacked via a Man In The Middle (MiTM) attack, which can pose a serious security vulnerability to users of your app.

2017年5月31日 1:52

[…] 1.关于苹果警告的理解:http://blog.cnbang.net/internet/3374/ 2.GitHub论坛:https://github.com/bang590/JSPatch/issues/746 […]

[…] 关于苹果警告 […]

[…] 关于苹果警告 […]