應用沙箱

Android平台利用Linux基於使用者的保護來識別和隔離應用程式資源。這可以將應用程式彼此隔離,並保護應用程式和系統免受惡意應用程式的侵害。為此,Android 為每個 Android 應用程式分配一個唯一的使用者 ID (UID),並在自己的進程中運行它。

Android 使用 UID 來設定核心級應用程式沙箱。核心透過標準 Linux 設施(例如分配給應用程式的使用者和群組 ID)在進程層級強制實施應用程式和系統之間的安全性。預設情況下,應用程式無法相互交互,並且對作業系統的存取也受到限制。如果應用程式 A 嘗試執行惡意操作,例如讀取應用程式 B 的資料或未經許可撥打電話,則它會被阻止這樣做,因為它沒有適當的預設使用者權限。該沙箱簡單、可審計,並且基於數十年歷史的 UNIX 風格的進程和文件權限用戶分離。

由於應用程式沙箱位於核心中,因此此安全模型擴展到本機程式碼和作業系統應用程式。核心之上的所有軟體,例如作業系統庫、應用程式框架、應用程式運行時和所有應用程序,都在應用程式沙箱中運行。在某些平台上,開發人員受限於特定的開發框架、API 集或語言。在 Android 上,對於如何編寫增強安全性所需的應用程式沒有任何限制;在這方面,本機代碼與解釋代碼一樣被沙箱化。

保護措施

一般來說,要在正確配置的裝置中突破應用程式沙箱,必須損害 Linux 核心的安全性。然而,與其他安全功能類似,實施應用程式沙箱的單獨保護並非無懈可擊,因此深度防禦對於防止單一漏洞導致作業系統或其他應用程式受到損害非常重要。

Android 依靠多種保護措施來實施應用程式沙箱。這些強制措施隨著時間的推移而引入,並顯著增強了最初基於 UID 的自主存取控制 (DAC) 沙箱。先前的 Android 版本包含以下保護:

  • 在 Android 5.0 中,SELinux 在系統和應用程式之間提供了強制存取控制 (MAC) 分離。然而,所有第三方應用程式都在同一 SELinux 上下文中運行,因此應用程式間隔離主要由 UID DAC 強制執行。
  • 在 Android 6.0 中,SELinux 沙箱進行了擴展,可以跨每個實體使用者邊界隔離應用程式。此外,Android 還為應用程式資料設定了更安全的預設值:對於targetSdkVersion >= 24的應用程序,應用程式主目錄的預設DAC 權限從751 更改為700。這為私有應用程式資料提供了更安全的預設值(儘管應用程式可能會覆寫這些預設值) 。
  • 在 Android 8.0 中,所有應用程式都設定為使用seccomp-bpf過濾器運行,該過濾器限制了應用程式允許使用的系統調用,從而加強了應用程式/核心邊界。
  • 在 Android 9 中,所有targetSdkVersion >= 28的非特權應用程式都必須在單獨的 SELinux 沙箱中運行,為每個應用程式提供 MAC。這種保護改善了應用程式的分離,防止覆蓋安全預設值,並且(最重要的是)防止應用程式使其資料世界可存取。
  • 在 Android 10 中,應用程式對檔案系統的原始視圖有限,無法直接存取 /sdcard/DCIM 等路徑。但是,應用程式保留對其特定於套件的路徑的完整原始存取權限,如任何適用方法(例如Context.getExternalFilesDir())返回的路徑。

共享文件指南

將應用程式資料設定為全球可存取是一種糟糕的安全實踐。存取權限授予所有人,且不可能將存取權限限制為僅指定的收件者。這種做法導致了資訊外洩和混亂的代理漏洞,並且是針對具有敏感資料的應用程式(例如電子郵件用戶端)的惡意軟體最喜歡的目標。在 Android 9 及更高版本中,對於targetSdkVersion>=28的應用程式明確禁止以這種方式共享檔案。

共享文件時請遵循以下準則,而不是讓應用程式資料可供全世界存取:

  • 如果您的應用程式需要與其他應用程式共用文件,請使用內容提供者。內容提供者以適當的粒度共享數據,並且沒有全球可存取的 UNIX 權限的許多缺點(有關詳細信息,請參閱內容提供者基礎知識)。
  • 如果您的應用程式具有真正應該可供全世界存取的檔案(例如照片),則它們必須是特定於媒體的(僅限照片、影片和音訊檔案)並使用MediaStore類別進行儲存。 (有關如何添加媒體項目的更多詳細信息,請參閱從共享存儲訪問媒體文件。)

Storage運行時權限控制透過MediaStore對強類型集合的存取。為了存取弱類型檔案(例如 PDF 和MediaStore.Downloads類別),應用程式必須使用ACTION_OPEN_DOCUMENT意圖等意圖。

若要啟用 Android 10 行為,請使用requestLegacyExternalStorage清單屬性,並遵循應用程式權限最佳實務

  • 對於面向 Android 9(及更低版本)的應用,清單標誌預設值為true
  • 對於面向 Android 10 的應用程序,預設值為 false。要在面向 Android 10 的應用程式中暫時選擇退出篩選儲存視圖,請將清單標誌的值設為true
  • 使用受限權限,安裝程式將允許非沙盒儲存的應用程式列入白名單。非白名單應用程式被沙盒化。