Android 平台會利用 Linux 使用者為基礎的防護機制,識別及隔離應用程式資源。這麼做可將各個應用程式隔離,並保護應用程式和系統免於惡意應用程式的攻擊。為此,Android 會為每個 Android 應用程式指派不重複的使用者 ID (UID),並在其專屬程序中執行。
Android 會使用 UID 設定核心層級的應用程式沙箱。核心會透過標準 Linux 設施 (例如指派給應用程式的使用者和群組 ID),在程序層級強制執行應用程式與系統之間的安全性。根據預設,應用程式無法彼此互動,且對作業系統的存取權受限。如果應用程式 A 嘗試執行惡意行為,例如未經授權讀取應用程式 B 的資料或撥打電話,由於沒有適當的預設使用者權限,因此會遭到禁止。沙箱簡單易懂,可進行稽核,而且是以數十年前 UNIX 風格的使用者分離程序和檔案權限為基礎。
由於應用程式沙箱位於核心中,因此這個安全性模型會擴展至原生程式碼和 OS 應用程式。核心以上的所有軟體 (例如 OS 程式庫、應用程式架構、應用程式執行階段和所有應用程式) 都會在應用程式沙箱中執行。在某些平台上,開發人員必須使用特定的開發架構、一組 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
。 - 使用受限制的權限,安裝程式會將允許使用非沙箱儲存空間的應用程式加到許可清單。未列入許可清單的應用程式會受到沙箱機制限制。