很多 iOS 開發者收到 Apple 警告郵件,是要全面封殺熱修復方案嗎?

最近不少 iOS 開發者都收到 Apple 警告郵件,有人以為是用了 JSPatch 的熱修復更新技術導致,但是很多沒有用 JSPatch 的App 也收到相似的郵件。

1、如果你沒有收到郵件,到你們的iTunes Connect 看一下,可能在那裡會有警示??
2、使用了 RN 和 WeeX 的同學你們收到類似的警示了么?

很多 iOS 開發者收到 Apple 警告郵件,這是要全面封殺熱修復方案?


這麼說吧,熱修復是絕對要禁止的,因為熱修復完全可以破壞商店的審核機制。

而商店的生態環境是開發者應當珍惜的!審核慢不能和你業務的發展畫等號,絕大多數公司的策劃,產品,開發能力,還輪不到審核速度背鍋。偏愛熱修復其實恰恰是拿來給自己垃圾的管理,開發擦屁股用的。

作為開發者,我理解並支持蘋果的做法。


「以前審核周期慢,你們玩熱更新熱修復睜一隻眼閉一隻眼就算了,現在審核就一兩天,還玩就不對了。大兒子OC被你們逼的沒有活路,小兒子swift還沒長大成年,你們卻拿我的平台養js這個小婊砸。現在我要開始管了,你們都得叫爸爸」。 —React-Native從入門到下架論平台的重要性

來自@App小公主 在微信公眾號截圖


蘋果的郵件說得很清楚吧

第一句就說了重點 你的代碼會在應用審核後改變功能

現在國內很多的應用都涉嫌違規,往往是靠審核時關閉違規功能,審核後打開違規功能來矇混過關。

蘋果要維護自己的審核機制,打擊熱更新是必然的。


Google Play表示一直禁止


前ios開發人員,現在前端一枚,早晨鼓搗以前代碼的時候看到群里的小夥伴門在討論這個問題。也沒啥利益相關的,看了看群里的小夥伴們的嘰嘰喳喳的討論,我也就順便看了看蘋果發的警告郵件。

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開發人員計劃許可協議和應用的第3.3.2節商店審查指南2.5.2。此代碼與遠程資源相結合,可以幫助對應用程序的行為進行重大更改,與最初對App Store進行審核相比。雖然當前可能不使用此功能,但它可能會載入私有框架,私有方法,並支持未來的功能更改。

這包括將任意參數傳遞給動態方法(如dlopen(),dlsym(),respondingToSelector :, performSelector :, method_exchangeImplementations())和運行遠程腳本以便更改應用程序行為或調用SPI的任何代碼,下載的腳本。即使遠程資源不是故意惡意的,它也可能很容易被劫持通過中間人(MiTM)攻擊,這可能對您的應用程序的用戶造成嚴重的安全漏洞。

請對您的應用執行深入審核,並刪除符合上述功能的任何代碼,框架或SDK,然後再提交下一個更新以供審核。

蘋果的開發協議中涉及的以上3.3.2和3.5.2的條款是:

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.

Apple開發者計劃許可協議

3.3.2應用程序不得下載或安裝可執行代碼。 解釋代碼只能是

在應用程序中使用,如果所有腳本,代碼和解釋器都打包在應用程序中,而不是

下載。 上述的唯一例外是由Apple的內置WebKit框架下載和運行的腳本和代碼,只要這些腳本和代碼不會改變應用程序的主要目的,通過提供與預期的和廣告的目的不一致的特性或功能 應用程序提交到App Store。

App Store審查指南

2.5.2應用程序應該在其包中自包含,並且不能在指定容器區域之外讀取或寫入數據,也不能下載,安裝或執行代碼,包括其他iOS,watchOS,macOS或tvOS應用程序。

蘋果的應用審核今天發出的郵件通知,據說是對jspatch的框架進行的警告。不過暫時我也沒能力確定,因為也有小夥伴表示並未引用jspatch也收到了郵件。而且某些事情大家如果都在猜的話陰謀論也就出來了。

不過也有說法說的也很在理,比如在github上看到的:

作為吃瓜群眾一枚,我也不知道是不是以後對混合式應用的審核都會不會更加嚴厲,也不知蘋果的下一步動作。

我所在的公司暫時還沒有使用熱更新的應用上架,原本的計劃是下半年web平台完成後會轉混合式應用,不過進度看現在的情況需要重新確定了。

只能說對這件事持續關注中!


作為遊戲從業者,我會告訴你如果不禁止,有些開發者為了過審,一個包封兩個遊戲進去,美國ip進去可能是消消樂,過審後鬼知道變成了什麼…


其實很多人並沒有意識到這次封殺的主要原因是什麼。我之前也沒有在意,只認為其可能存在中間人攻擊問題。

事實上,JSPatch 以及 wax(可能由於使用範圍不大沒被波及)這類熱更新系統的實現原理皆是實現了另外一種語言(這裡是JS和Lua)到Objective-C 的 Bridge。個人認為以此來做 hotfix 無可厚非,畢竟蘋果審核是很讓人蛋疼的。

但這同時帶來了一個很嚴重的問題,當中間人攻擊和這個 Bridge 結合在一起的時候就出來大問題了:在當前應用沙盒內的任意代碼執行

由於 JSpatch 本身並不包含安全性校驗,很多開發者也沒有自己去做,這會導致別有用心的人可能對用戶進行中間人攻擊,從而下發自己的代碼,而且這個執行代碼是沒有任何限制的(沙盒內)。比如,小白用戶在使用應用時,突然彈出框讓輸蘋果賬號和密碼,這個後果還是很嚴重的。

這也就是為什麼 React Native 並沒有受到影響的原因。


ionic2寫的程序,前2天提交的審核,昨天晚上收到郵件,通過了。裡面集成了熱更新。沒什麼問題。RNer,來學ionic吧。

另外說下為什麼收到警告,說RN其實是玩笑話,說的有點躺槍,熱更新技術應該也不是問題,沒準只是jspatch本身的問題,或者說漏洞,才導致被封(警告)的,補一個去年的新聞,其實已經暗示到了今天。

補一個聲音,侵刪

RN給的解釋:


看了下Github上的討論,蘋果禁的是 rollout.io, JSPatch 這類具備修改native代碼的能力的框架,至於從遠程下載JavaScript代碼來執行,蘋果 3.3.2條款是明確規定允許的:

The only exception to the foregoing is scripts and code downloaded and run by Apple"s built-in WebKit framework or JavascriptCore

因此 Code Push 這種熱更新JavaScript代碼的工具應該不會受到影響。Github上有人報告自己用React Native+ Code Push寫的App被審核通過了。

如果你的Weex/React Native 寫的App連Code Push都沒用到,沒有熱更新能力,那就更不會收到影響了。

英文好的小夥伴可以訂閱 GitHub上的這個 Issue A warning from Apple · Issue #12778 · facebook/react-native ,獲取第一手消息


說實話覺得現在蘋果的審核速度已經快了許多了,再次發版的成本大多也並非不可接受了。

再說用著熱更新技術的公司,有多少是只用來改改嚴重的線上bug的?有多少違背蘋果開發協議的做法是用熱更新來繞過審核的呢?


會原生,會混合的搬著小板凳看看戲,反正我自己做的全是原生,工作上boss需要啥我就給做啥,基本處於無傷狀態;

設身處地換位思考想想:

其實對事件反映最大的應該屬於只會一種的人吧,只會原生的開始竊喜,只會套殼的開始憂心這波形勢引起的iOS開發又回到以前的較高門檻;

個人覺得其實大家的討論意義都不大,都是事關自己未來飯碗而發出的帶有強烈主觀情緒的談論,並不具備足夠的客觀性和很強的理性層次,有時間噴或捧不如著手對另一方向的開發做個較好的了解,無論是否會傷害到套殼開發者,在將來總有一方會成為弱勢,不如兩者都會,雙保險萬無一失


關於蘋果警告 - bang』s blog

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

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


實名反對輪子哥 @vczh 現在審核不慢了。

「以前審核周期慢,你們玩熱更新熱修復睜一隻眼閉一隻眼就算了,現在審核就一兩天,還玩就不對了。大兒子OC被你們逼的沒有活路,小兒子swift還沒長大成年,你們卻拿我的平台養js這個小婊砸。現在我要開始管了,你們都得叫爸爸」—熱修復從入門到下架論平台的重要性

圖文來自網路,侵刪。


說得很明白了,不可以遠程下載代碼用於改變程序行為,不然還審核什麼?過審之後你直接熱更新把什麼都改掉,這怎麼可以?

根本不是具體的框架或者系統調用的問題。你的框架僥倖過了,但本質還是違規,誰能保證以後不查出來?

contain code designed explicitly with the capability to change your app』s behavior or functionality after App Review approval

很明顯就是不允許熱更新,更新都要通過審核流程。早就是這樣了吧,以前執行不嚴而已。你們都沒有意識到這個政策風險…

本質就是要控制app的行為,他讓你做你才能做。任何可能削弱他的影響力的技術都有可能被禁,才不管你熱更新有多方便

當然,道高一尺,魔高一丈,想繞過還是不難的。私有的vm和執行格式,不開源,不流行,技術上是很難檢測出來的。可執行代碼偽裝成圖片或者其他資源,vm也是編譯後的native代碼,除非從程序本身去觀察取證。當然,技術水平不夠的,就沒辦法了


實名反對@姚先生 。先上一張2016年10月查看蘋果開發者協議時的截圖。

The only exception to...

以貴乎平均年薪百萬的英語水平想必不用翻譯也都能看懂,載入運行由JSCore執行的代碼是被允許的,這也並沒有破壞iOS的沙盒安全機制。

至於截圖中說明的安全隱患,我查看過FireEye原文和JSPatch作者bang的回復,作者對安全的問題做了一一回應,漏洞發生在傳輸階段,做好文件完整性校驗和非對稱加密可以解決。

至於ReactNative沒有受影響主要原因應該是RN的主要目的是為了解決跨平台的開發效率,熱更新沒有被濫用,而且據我了解RN和Cordova都可以使用M$的codepush方案,基於Cordova的ionic和RN在這次集中處理中可以說是雨露均沾的赦免。要知道同樣沒有受影響的還有通過下發位元組碼執行的手機QQ,陰陽師最火爆的時候我留意過在首次上架的一個月內遊戲的更新都是通過所謂的HotPatch。

蘋果一直在努力維護的軟硬體結合的平台,如果因為熱更新而喪失了控制權,是蘋果核消費者都不願意麵對的結果,同時高度依賴熱更新而忽略開發階段測試工作對於整個行業也不是好的風氣。

最後附上一段滴滴iOS動態化方案DynamicCocoa作者的評價,侵刪。


就是想知道12306如果被封了會怎麼樣。

具體就是大家會罵鐵總憑什麼不不按蘋果要求做呢?讓大家都買不到票。

還是蘋果為什麼不能弄個特例,讓大家都買上票。

反正都是不會輕易讓步的。


RN應該是沒事的


一app收到警告、另一app未收到。關鍵是我們兩個都沒有使用諸如RN、weex、JSPath……只是說,在審核狀態的時候,後台有一些開關控制一些界面顯示與否,說好的代碼檢查,那我不懂它怎麼發過來了


直接複製下下午寫的,看到有的博客說會封殺rn,就去瞅了瞅,

最初在 HN 上看到,這次波及的主要是 JSPatch 與 Rollout 的使用者;Rollout 的 CEO Erez Rusovsky 表示我們一直是遵紀守法好公民,而且蘋果也不是只封殺 Rollout,肯定不會是因為我們做的有什麼問題;我們的應用廣泛嵌入到了數以千記的 APP 中,我就不信蘋果敢這麼狠。然後下面開始了對於蘋果和 Rollout 的群嘲。。。

然後下面進入 React Native 的討論,有部分 React Native 的應用同樣被 KO 了,不過 Rollout 與 JSPatch 被蘋果點名的主要問題是exposes arbitrary, uncontrolled access to native APIs.,即對上暴露了本地介面的調用許可權。然後使用 RN 但是也被警告的開發者表示,他發現自己的應用中使用了 RCTUtils 這個唯一調用動態方法的類;對此 ide 表示 RCTSwapClassMethods 以及 RCTSwapInstanceMethods 明明只是 RN 內部使用的,並沒有暴露給 JavaScript。而 Apple 官方的聲明是:An Application may not download or install executable code ,React Native 肯定沒有破壞這個條約,並且 Apple 也允許使用 JavaScriptCore 更新代碼:The only exception to the foregoing is scripts and code downloaded and run by Apple"s built-in WebKit framework or JavascriptCore. React Native 的熱更新本來就是更新 JavaScript 代碼,才不是 Patch 原生代碼呢。


請問unity上的lua這類熱更新方案是不是也不能用了?

(我還不會熱更新,是不是就不用學了?)


推薦閱讀:

一個有 15 個頁面的項目怎麼規範 css 樣式?
iOS 設備和電腦間傳輸文件有沒有比較好的方案?
為什麼蘋果在很早之前開發一個自己的iOS很容易,而現在中國很多互聯網巨頭卻無法擁有真正屬於自己的系統?
從實際體驗來看,M7 處理器是否為 iPhone 5s 的續航帶來了顯著提升?
如何看待蘋果年底前在華建設第一座亞太研發中心?

TAG:iOS | iOS開發 | ReactNative | JSPatch |