當前位置: 妍妍網 > 碼農

Python程式因一個字串被蘋果App Store封殺?開發者:稽核規則太黑了!

2024-07-05碼農

轉自:CSDN(ID:CSDNnews)

只因升級一下程式語言的版本,就導致開發的套用被拒、稽核不透過、上架不了市集,這種鮮少發生的事情如今正在一些 Python 開發者身上上演。

近日,據外媒 LWN 報道,一些開發者在將他們的應用程式中使用的 Python 版本從 3.11 升級到 3.12 版本後,重新送出到蘋果 App Store 時,遭到了蘋果稽核團隊的拒絕。

這也引起了許多開發者的關註。那麽,問題究竟出在 Python 3.12 還是蘋果稽核團隊?

一個字串導致 App 稽核失敗

回看事情經過,起因是一位名為 Eric Froemling 的開發者在 GitHub Python 倉庫的 issue 中分享了他的遭遇,其表示:

這並不是一個傳統意義上的 bug,但我最近經歷了一場磨難。我的套用在蘋果的 App Store(具體是 Mac App Store)上更新之後,因為我將使用的 Python 版本從 3.11 更新到 3.12,導致更新被拒絕了。

起初,Eric Froemling 也並不明白此前可以正常上架的應用程式,為什麽做了一下叠代後就不可以了。與此同時,App Store 稽核團隊在拒絕 Eric Froemling 的 App 時也沒有直接說明原因,只冰冷地回復一句 「我們無法為您提供更多資訊」。

幾經折騰, Eric Froemling 終於忍無可忍,向蘋果團隊送出了一份申訴信件,蘋果這才給他一定的提示:

根據指南 2.5.2 條 ——效能——軟體要求

應用程式安裝或啟動了可執行程式碼。具體來說,該應用程式使用 itms-services URL 方案安裝應用程式。

稍作解釋,itms-services URL 方案是蘋果公司提供的一種用於分發和安裝 iOS 應用程式的方式,通常用於分發不在 App Store 上釋出的套用,如企業內部套用或測試版套用。它允許使用者透過點選一個連結直接在他們的 iOS 裝置上安裝應用程式,而無需透過 App Store。

以下是一個基本的 itms-services URL 結構:

itms-services://?action=download-manifest&url=https://example.com/manifest.plist

其中:

  • itms-services://:這是 URL 方案,用於告訴 iOS 裝置這是一個套用安裝請求。

  • ?action=download-manifest:指定要執行的操作,這裏是下載套用的清單檔。

  • url=https://example.com/manifest.plist:指定清單檔(manifest file)的 URL,清單檔包含套用的詳細資訊,包括套用包的下載地址。

  • 經過大量的排查, Eric Froemling 發現違規檔是 Lib/urllib/parse.py(Python 標準庫的 Urllib 解析器)及其關聯的 .pyc 。在 Python 3.12 程式碼中,似乎添加了一個「itms-services」字串,而蘋果 App Store 似乎正在掃描這個字串,並自動拒絕包含它的任何內容(Eric Froemling 稱至少在他的案例中是這樣)。

    最終,Eric Froemling 從他的 Python 程式碼中刪除該字串後,更新後的 App 終於透過了稽核,成功上架 App Store。

    引發爭議的蘋果稽核及反饋規則

    令 Eric Froemling 郁悶的其實並非是「itms-services」字串埋下的「坑」,而是蘋果 App Store 的稽核規則。

    他表示,「當蘋果公司最終告訴我,Lib/urllib/parse.py 及其關聯的 .pyc 是有問題的檔時,此時追蹤到底發生了什麽並不難。現在回想起來,我感到很沮喪,我沒有想到早點透過 Python 本身對 itms-services 進行全文搜尋,也沒有偶然發現其他人遇到這種情況。」

    時下, Eric Froemling 耗費了大量的精力進行 Debug,只刪除了一個字串就解決問題,在不少開發者看來,「其實本可以透過蘋果透明的稽核機制來避免的,然而現實就是,蘋果的稽核機制不透明」。

    CPython 核心開發者:App Store 稽核規則既偏執又難以捉摸!

    對此,CPython 核心開發者 Russell Keith-Magee 在看到 Eric Froemling 送出的 issue 後,隨即釋出了 一篇【處理與 App Store 稽核流程不相容的問題】文章,把這個事情單獨擰出來說了一遍。

    Russell Keith-Magee 稱,這個問題也 為 CPython 核心開發團隊提出了一個有趣的哲學問題: 我們願意為適應 App Store 稽核流程付出多大努力?

    Russell Keith-Magee 解釋稱,之所以發生這種情況,問題在於蘋果公司的 macOS App Store 會自動拒絕任何包含 itms-services 字串的應用程式。 蘋果的 macOS 商店分發的軟體是經過沙盒處理的, 經過沙盒處理的應用程式禁止使用帶有 itms-services 方案的 URL。

    蘋果的自動審查程式會捕捉到 urllib 解析器中處理這些 URL 的程式碼,即使相關 應用程式從未使用過 itms-services:// URL 也是如此。標準庫中就有這樣的程式碼,因此應用程式會被拒。

    對字串進行一些輕度混淆似乎可以避免這一問題。 不過,這並不能保證永遠都能解決這個問題,而且可能會引發混亂,也不能保證這將是我們需要解決的唯一一個應用程式驗證問題」,Russell Keith-Magee 說,「雖然現在引發問題的是一個 macOS 套用,但類似的 App Store 自動稽核流程也存在於 iOS、Android 和微軟平台市集中。 蘋果的稽核無疑是其中最......偏執和高深莫測的......,它們的驗證和驗收流程完全不透明」

    回歸問題本身,這次導致 App 稽核不透過的原因是 Python 3.12 中包含了「itms-services」字串,作為官方如何解決這一問題,Russell Keith-Magee 給出了兩個建議:

    1. 新增程式語言設計的目標 將「符合應用程式商店要求」作為 CPython 的設計目標,並整合任何必要的修補程式來滿足這一要求。這意味著使用者不需要進行任何特殊的修補程式處理來使 CPython「相容市集」;但這也意味著有時會合並一些醜陋的混淆程式碼。如果某個時點規則發生變化,可能需要更多的修補程式;而如果某個舊規則被移除,我們將沒有明確的訊號來表明某個特定的混淆程式碼不再需要。

    2. 把這個視為一個分發問題。 開發時,使用 CPython 就正常用,只不過後面要使用生成打包應用程式的工具(如 Briefcase、Py2app、Buildozer 等)負責對 CPython 進行修補程式,使其符合市集的要求。就 Briefcase 和 Bulldozer 而言,這些工具還會修補和構建自訂 CPython 庫。從過往歷史上看,這是因為 CPython 並不支持 iOS 和 Android;Python 3.13 版本源碼現在無需打修補程式即可執行......但如果我們將此視為分發問題,那麽打修補程式將成為一項持續性要求。

    不過,這兩種方式也可能會導致兩個新問題的出現, Russell Keith-Magee表示:

  • (1) 的方式這也意味著分發的 Python 並不是「官方」的 Python,因為它們已經被修改以供分發;我不知道我們應該如何考慮這是否存在安全或品牌風險。我猜,Linux 發行版在釋出 Python 時打的修補程式與此類似,也許這並不是一個問題。

  • 對於(2),還有一個額外的問題,即 CPython 是否應該記錄它所知道的 App Store 稽核的各種限制。

  • 因此,CPython 應該如何處理這種混淆?

    對此,另一位 CPython 核心開發者 Alex Gaynor 提出了第三種方案:

    靈感來源於我們在 pyca/cryptography 上的經驗啟發。我們經常收到錯誤報告,說「你拒絕解析這張證書,雖然它在技術上是無效的,但它是由[某個廣泛使用的裝置或 CA]簽發的」。我們得出的答案是:

    一般來說,我們會接受能解決這類問題的 PR,前提是這些 PR 要小,要在地化,而且一般不會太糟糕。但是,在我們合並 PR 之前,需要有人向第三方投訴(如蘋果 App Store),並確保他們意識到了這個問題,並表示他們會采取一些措施來解決這個問題。我們接受的任何解決方法都會有一定的時間限制(即我們會在幾個版本中刪除解決方法)。

    這樣既能讓使用者獲得良好的 OOTB 體驗,又不會讓大公司簡單地將其怪異問題外部化到 OSS 計畫中,從而在兩者之間保持平衡。

    6 月 20 日,Keith-Magee 寫道,他想到了另一種方法:與其混淆原始碼(蘋果可能會認為這是「試圖規避合法的安全審查程式」),不如在構建時添加一個選項,刪除我們知道有問題的程式碼。

    Mac 資料夾將包含一個 diff,其中描述了需要套用到原始碼樹中的改動(在本例中,刪除了 parse.py 中對 itms-server URL 的支持;但如果需要,也可以擴充套件)。

    configure 將獲得一個 --with-app-store-patch 選項。在大多數平台(包括 macOS)上,該選項預設為禁用,但在 iOS 上會啟用。如果啟用,它將在構建標準庫之前套用修補程式。該選項也可以接受一個檔(即,--with-app-store-patch=path/to/patch),這樣,如果在特定 Python 版本的維護視窗關閉後,App Store 的規則在未來某個時間發生了變化,發行商仍有一個受支持的選項來提供更新的修補程式。

    是的,這實質上是復制了分銷商可以輕易復制的東西,但它的好處是,CPython 作為一個計畫,可以提供一個官方列表,列出 App Store 合規性所需的更改。

    這聽起來更容易讓人接受嗎?

    最後

    最終,結果幾天內部思考,Keith-Magee 在 6 月 25 日回復道,「感謝大家的意見,我剛剛送出了#120984(https://github.com/python/cpython/pull/120984)來實作該--with-app-store-compliance 選項」,以此解決因字串導致 App 被 App Store 拒之門外的事情。他在請求中提到,這個選項可以用於 iOS 和 macOS 以外的平台,但目前沒有這樣的使用案例。如果一切順利,它將在 Python 3.13 中可用。

    令人沮喪的是,不少開發者反饋,像 Python 這樣的自由軟體計畫不得不浪費時間,想方設法繞過不透明的審查程式,以便開發人員能夠為非自由平台編寫軟體。HN 網友評價道:

    不只是蘋果公司會玩這種把戲。

    試試用 PyInstaller 編譯 Python 應用程式,同時開啟 Windows Defender 即時掃描(預設設定)。如果沒有 Defender 的阻止,你甚至無法編譯二進制檔。

    同樣,嘗試在開啟 Windows Defender 的情況下執行 PyInstaller 生成的二進制檔。Defender 會說這是惡意程式,不會執行它。

    兩個主要的作業系統平台都不遺余力地阻止你釋出和執行 Python 應用程式,這有點反烏托邦。

    在這一次經歷中,CPython 核心開發者 Keith-Magee 和其他 CPython 開發者還能果斷站出來,其所采取的方法似乎是為 Python 應用程式開發者提供最佳體驗的最省事的選擇。然而,幾乎可以肯定,這不會是最後一次有計畫遇到這個問題。

    來源:

    https://lwn.net/SubscriberLink/979671/4fb7c1827536d1ae/

    https://discuss.python.org/t/handling-incompatibilities-with-app-store-review-processes/56011/15

    https://news.ycombinator.com/item?id=40815130

    - EOF -