如何評價2017年3月8日蘋果針對熱更新方案採取的行動?

今日凌晨,很多公司都收到了以下這封郵件。

很多新提交的App也因此被拒。

GitHub:https://github.com/bang590/JSPatch/issues/746


轉自Apple向熱更新下達最後通牒 - 天狐博客

之前開發者都收到了蘋果2017年的新開發者審核協議更新通知

2017年3月8...注意..是女神節這天。大量開發者收到了被拒絕 被警告的郵件,內容如下:

Dear Developer,
Your app, extension, and/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 section 3.3.2 of the Apple Developer Program License Agreement and App Store Review Guideline 2.5.2. 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 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.
Please perform an in-depth review of your app and remove any code, frameworks, or SDKs that fall in line with the functionality described above before submitting the next update for your app for review.
Best regards,
App Store Review

蘋果審核協議中有這樣一節:

Apple Developer Program License Agreement
3.3.2 An Application may not download or install executable code. Interpreted code may only be
used in an Application if all scripts, code and interpreters are packaged in the Application and not
downloaded. The only exception to the foregoing is scripts and code downloaded and run by Apple"s builtin WebKit framework, provided that such scripts and code do not change the primary purpose of the Application by providing features or functionality that are inconsistent with the intended and advertised purpose of the Application as submitted to the App Store.
App Store Review Guideline
2.5.2 Apps should be self-contained in their bundles, and may not read or write data outside the designated container area, nor may they download, install, or execute code, including other iOS, watchOS, macOS, or tvOS apps.

隨後JSPatch群里 ,github上都炸了鍋 : https://github.com/bang590/JSPatch/issues/746

react-native 的情況:https://github.com/facebook/react-native/issues/12778

Weex :https://github.com/alibaba/weex/issues/2875

JSPatch的作者bang也收到了郵件:

為什麼突然爆發

突然爆發並非偶然,蘋果的審核指南一直明確,禁止下載可執行代碼,雖然JSPatch等庫使用了JavaScriptCore來巧妙的實現,但也不是長久之計,很多開發者不自覺的使用其來下發私有方法等等行為遲早會被蘋果發現。也極大的威脅到了極其注重安全的蘋果

再有就是一切涉及到網路的都會有安全的風險

還有一個有意思的事實,昨天VS2017發布,號稱內置iOS模擬器,直接開發React Native:

所以很多人也得出了一個災難性結論"蘋果封殺混合開發",JSPatch等熱更新是誤傷....

為什麼沒使用熱更新會受到郵件

個人認為蘋果是批量掃描runtime並且群發的,蘋果沒辦法批量檢測remote script(遠程腳本下載)

所以機智的檢測熱更新可能使用到的runtime方法,比如method_exchangeImplementations。這樣基本全覆蓋了那些使用熱更新的APP。

讓下載腳本代碼且使用runtime方法實現的的人下一個版本改掉,如果不改。就被下架被拒絕上架。

JSPatch是"下載腳本代碼且使用runtime",並不是針對JSPatch一個庫

rollout.js,react native,weex都會有這種提示。

Runtime不能繼續用了?

個人認為原生代碼中使用runtime還是沒問題,只是為了提醒那些使用了runtime並且下載遠程腳本改變app行為的人。

如果蘋果把runtime變成私有方法或去掉.那麼Objective-C的優勢大大的沒有了.....

怎麼解決?

如果是類JSPatch這種只用來熱更新的,暫時去掉這些熱更新的庫吧,或者觀望陣子再上架新包。

如果是類React Native,抓緊轉行吧。。哈哈哈(我開玩笑的。。。)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

圍觀時還請不要灌水什麼的。


昨天早上 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。

第一點警告郵件和代碼檢查使得使用門檻變高了,顯然會減少使用人數。第二點第三點只要有一個平台來管控,是可以做到的,可能的話希望能跟蘋果審核團隊協商。

轉自bang的博客 關於蘋果警告 " bang』s blog


推薦閱讀:

為什麼國內用戶不怎麼使用iOS自帶應用(Messages和FaceTime、Reminders…)?
iOS、Android、Windows Phone 系統在移動終端(手機和平板)各有什麼利弊?
ipad air 2升級ios11.2出現大量軟體卡在登錄界面然後閃退,是系統原因還是軟體原因?
新浪微博客戶端的 iOS 推送為何會比安卓慢?
iOS 上有什麼好的聽書應用?

TAG:iOS | 蘋果公司AppleInc | iOS開發 | ReactNative |