實施安全

Android 安全團隊定期收到有關防止 Android 裝置上潛在安全問題的資訊請求。我們偶爾也會抽查設備,並讓設備製造商和受影響的合作夥伴了解潛在問題。

本頁面根據我們的經驗提供安全最佳實踐,擴展了我們為開發人員提供的安全設計文檔,並包含在設備上建置或安裝系統級軟體的獨特詳細資訊。

為了促進這些最佳實踐的採用,Android 安全團隊盡可能將測試納入Android 相容性測試套件(CTS) 和Android Lint 。我們鼓勵裝置實作者貢獻可以幫助其他 Android 使用者的測試(在root/cts/tests/tests/security/src/android/security/cts中查看與安全性相關的測試)。

開發流程

在您的開發流程和環境中使用以下最佳實務。

審查原始碼

原始碼審查可以檢測廣泛的安全性問題,包括本文檔中確定的問題。 Android 強烈鼓勵手動和自動原始碼審查。最佳實踐:

  • 使用 Android SDK 對所有應用程式程式碼運行Android Lint並修正任何已識別的問題。
  • 應使用自動化工具來分析本機程式碼,該工具可以偵測記憶體管理問題,例如緩衝區溢位和相差一錯誤。
  • Android 建置系統支援許多 LLVM 清理程序,例如可用於此目的的 AddressSanitizer 和 UndefinedBehaviorSanitizer。

使用自動化測試

自動化測試可以檢測廣泛的安全性問題,包括下面討論的幾個問題。最佳實踐:

  • CTS定期更新安全性測試;運行最新版本的 CTS 以驗證相容性。
  • 在整個開發過程中定期執行 CTS,以便及早發現問題並縮短修正時間。 Android 使用 CTS 作為我們的自動化建置流程中持續整合的一部分,該流程每天會建置多次。
  • 設備製造商應該自動化介面安全測試,包括使用格式錯誤的輸入進行測試(模糊測試)。

簽署系統鏡像

系統映像的簽章對於確定裝置的完整性至關重要。最佳實踐:

  • 設備不得使用公開的金鑰進行簽署。
  • 用於簽署設備的金鑰的管理方式應符合處理敏感金鑰的業界標準實踐,包括提供有限、可審核存取的硬體安全模組 (HSM)。

簽署應用程式 (APK)

應用程式簽名在設備安全中發揮重要作用,用於權限檢查和軟體更新。選擇用於簽署應用程式的金鑰時,重要的是要考慮應用程式是僅在單一裝置上可用還是在多個裝置上通用。最佳實踐:

  • 應用程式不得使用公開的金鑰進行簽署。
  • 用於簽署應用程式的金鑰的管理方式應符合處理敏感金鑰的行業標準實踐,包括提供有限、可審核存取的 HSM。
  • 應用程式不應使用平台密鑰進行簽署。
  • 具有相同包名的應用程式不應使用不同的金鑰進行簽署。當為不同裝置建立應用程式時,尤其是使用平台金鑰時,通常會發生這種情況。如果應用程式與裝置無關,請跨裝置使用相同的金鑰。如果應用程式是特定於裝置的,請為每個裝置和金鑰建立唯一的套件名稱。

發布應用程式

Google Play 為裝置製造商提供了更新應用程式的能力,而無需執行完整的系統更新。這可以加快對安全問題的回應和新功能的交付,並提供一種方法來確保您的應用程式具有唯一的套件名稱。最佳實踐:

  • 將您的應用程式上傳到 Google Play 以允許自動更新,而無需完整的無線 (OTA) 更新。已上傳但未發布的應用程序,用戶無法直接下載,但應用程式仍會更新。之前安裝過該應用程式的用戶可以重新安裝它和/或安裝在其他裝置上。
  • 建立與您的公司明確相關的應用程式套件名稱,例如使用公司商標。
  • 裝置製造商發布的應用程式應上傳到Google Play商店,以避免第三方用戶冒充套件名稱。如果裝置製造商在裝置上安裝應用程式而未在 Play 商店上發布該應用程序,則其他開發人員可以上傳相同的應用程式、使用相同的套件名稱並更改該應用程式的元資料。當應用程式呈現給使用者時,這些不相關的元資料可能會造成混亂。

回應事件

外部各方必須能夠就特定於設備的安全問題聯繫設備製造商。我們建議建立一個可公開存取的電子郵件地址來管理安全事件。最佳實踐:

  • 建立security@your-company.com或類似地址並公開。
  • 如果您發現影響多個裝置製造商的 Android 作業系統或 Android 裝置的安全問題,您應該透過提交安全錯誤報告來聯絡 Android 安全團隊。

產品實施

實施產品時使用以下最佳實務。

隔離根進程

根進程是權限提升攻擊最常見的目標,因此減少根進程的數量可以降低權限提升的風險。 CTS 包括列出根進程的資訊測試。最佳實踐:

  • 設備應以 root 身分運行最少的必要程式碼。如果可能,請使用常規 Android 進程而不是根進程。 ICS Galaxy Nexus 只有六個根程序:vold、inetd、zygote、tf_daemon、ueventd 和 init。如果某個流程必須在裝置上以 root 身分執行,請在 AOSP 功能要求中記錄流程,以便公開審核。
  • 如果可能,根代碼應與不受信任的資料隔離並透過 IPC 存取。例如,將根功能減少為可透過 Binder 存取的小型服務,並將具有簽署權限的服務公開給處理網路流量的權限較低或沒有權限的應用程式。
  • 根程序不得偵聽網路套接字。
  • 根進程不得為應用程式(例如 Java VM)提供通用運行時。

隔離系統應用程式

一般來說,預裝應用程式不應使用共用系統 UID 來運行。但是,如果應用程式有必要使用系統的共用 UID 或其他特權服務,則該應用程式不應匯出可由使用者安裝的第三方應用程式存取的任何服務、廣播接收器或內容提供者。最佳實踐:

  • 設備應運行系統所需的最少代碼。如果可能,請使用具有自己的 UID 的 Android 進程,而不是重複使用系統 UID。
  • 如果可能,系統程式碼應與不可信資料隔離,並僅將 IPC 暴露給其他可信進程。
  • 系統程序不得偵聽網路套接字。

隔離進程

Android 應用程式沙箱為應用程式提供了與系統上其他進程(包括根進程和偵錯器)隔離的期望。除非應用程式和用戶專門啟用了調試,否則任何應用程式都不應違反該期望。最佳實踐:

  • 根進程不得存取各個應用程式資料資料夾中的數據,除非使用記錄的 Android 偵錯方法。
  • 根進程不得存取應用程式的內存,除非使用記錄的 Android 調試方法。
  • 設備不得包含任何存取其他應用程式或進程的資料或記憶體的應用程式。

保護 SUID 文件

新的 setuid 程式不應被不受信任的程式存取。 Setuid 程式經常是可用於取得 root 存取權的漏洞所在,因此請努力最大程度地減少 setuid 程式對不受信任的應用程式的可用性。最佳實踐:

  • SUID 程序不得提供可用於規避 Android 安全模型的 shell 或後門。
  • SUID 程式不能被任何使用者寫入。
  • SUID 程式不應該是全世界可讀或可執行的。建立一個群組,限制該群組成員對 SUID 二進位檔案的訪問,並將能夠執行 SUID 程式的任何應用程式放入該群組中。
  • SUID 程式是使用者裝置 root 的常見來源。為了降低這種風險,SUID 程式不應由 shell 使用者執行。

CTS 驗證程序包括列出 SUID 文件的資訊測試;根據 CTS 測試,某些 setuid 檔案是不允許的。

保護監聽套接字

當設備在任何連接埠、任何介面上偵聽時,CTS 測試都會失敗。如果發生故障,Android 會驗證是否使用了以下最佳實踐:

  • 設備上不應有偵聽連接埠。
  • 監聽埠必須能夠在沒有 OTA 的情況下被停用。這可以是伺服器或用戶設備配置更改。
  • 根進程不得偵聽任何連接埠。
  • 系統 UID 擁有的程序不得偵聽任何連接埠。
  • 對於使用套接字的本機 IPC,應用程式必須使用僅限某個群組存取的 UNIX 網域套接字。為 IPC 建立一個檔案描述符,並將其設定為特定 UNIX 群組的 +RW。任何客戶端應用程式都必須位於該 UNIX 群組內。
  • 一些具有多個處理器的裝置(例如與應用程式處理器分離的無線電/數據機)使用網路套接字在處理器之間進行通訊。在這種情況下,用於處理器間通訊的網路套接字必須使用隔離的網路接口,以防止裝置上未經授權的應用程式進行存取(即使用iptables來防止裝置上的其他應用程式進行存取)。
  • 處理偵聽連接埠的守護程式必須能夠抵禦格式錯誤的資料。 Google 可能會使用未經授權的用戶端(如有可能)使用授權用戶端對連接埠進行模糊測試。任何崩潰都將被歸檔為具有適當嚴重程度的錯誤。

記錄數據

記錄資料會增加資料暴露的風險並降低系統效能。由於 Android 裝置上預設安裝的應用程式記錄敏感使用者數據,已發生多起公共安全事件。最佳實踐:

  • 應用程式或系統服務不應記錄第三方應用程式提供的可能包含敏感資訊的資料。
  • 作為正常操作的一部分,應用程式不得記錄任何個人識別資訊 (PII)。

CTS 包括檢查系統日誌中是否有潛在敏感資訊的測試。

限制目錄訪問

全域可寫目錄可能會引入安全漏洞,並使應用程式能夠重新命名受信任的檔案、替換檔案或進行基於符號連結的攻擊(攻擊者可能使用檔案的符號連結來欺騙受信任的程式執行不應執行的操作)。可寫入目錄還可以防止應用程式卸載時正確清理與應用程式關聯的所有檔案。

作為最佳實踐,系統或 root 使用者建立的目錄不應該是全域可寫入的。 CTS 測試透過測試已知目錄來幫助實施此最佳實踐。

保護設定檔

許多驅動程式和服務依賴儲存在/system/etc/data目錄中的配置和資料檔案。如果這些檔案由特權進程處理且是全域可寫的,則應用程式可以透過在全域可寫檔案中製作惡意內容來利用該進程中的漏洞。最佳實踐:

  • 特權程序使用的設定檔不應該是所有人可讀的。
  • 特權程序使用的設定檔不得是全域可寫的。

儲存本機程式碼庫

特權設備製造商程序使用的任何代碼都必須位於/vendor/system中;這些檔案系統在啟動時以唯讀方式安裝。作為最佳實踐,系統或裝置上安裝的其他高權限應用程式使用的程式庫也應該位於這些檔案系統中。這可以防止可能允許攻擊者控制特權程序執行的程式碼的安全漏洞。

限制設備驅動程式訪問

只有受信任的程式碼才能直接存取驅動程式。在可能的情況下,首選體系結構是提供單一用途的守護程序,該程式代理對驅動程式的呼叫並限制驅動程式對該守護程序的存取。作為最佳實踐,驅動程式設備節點不應該是全域可讀或可寫入的。 CTS 測試透過檢查暴露驅動程式的已知實例來幫助實施此最佳實踐。

禁用亞銀

Android 調試橋 (adb) 是一種有價值的開發和調試工具,但設計用於受控的安全環境,不應啟用一般用途。最佳實踐:

  • 預設必須停用 ADB。
  • ADB 必須要求使用者在接受連線之前將其開啟。

解鎖引導程式

許多 Android 裝置支援解鎖,使裝置擁有者能夠修改系統分割區和/或安裝自訂作業系統。常見用例包括安裝第三方 ROM 以及在設備上執行系統級開發。例如,Google Nexus 裝置擁有者可以執行fastboot oem unlock來啟動解鎖過程,這會向使用者顯示下列訊息:

解鎖引導程式?

如果解鎖引導程序,您將能夠在此裝置上安裝自訂作業系統軟體。

自訂作業系統不會接受與原始作業系統相同的測試,並且可能會導致您的裝置和安裝的應用程式停止正常運作。

為了防止未經授權存取您的個人數據,解鎖引導程式也會刪除您裝置中的所有個人資料(「恢復原廠設定」)。

按下音量增加/減少按鈕選擇是或否。然後按電源按鈕繼續。

:解鎖引導程式(可能會使保固失效)

:不解鎖引導程式並重新啟動裝置。


作為最佳實踐,可解鎖的 Android 裝置必須在解鎖之前安全地刪除所有使用者資料。如果解鎖時未能正確刪除所有數據,則物理上鄰近的攻擊者可能會未經授權存取機密 Android 用戶數據。為了防止用戶資料洩露,支援解鎖的設備必須正確實現(我們已經看到了許多設備製造商不正確地實現解鎖的實例)。正確實施的解鎖過程具有以下屬性:

  • 當使用者確認解鎖命令時,設備必須立即開始資料擦除。在安全刪除完成前不得設定unlocked標誌。
  • 如果無法完成安全刪除,設備必須保持鎖定狀態。
  • 如果底層塊設備支持,則應使用ioctl(BLKSECDISCARD)或等效項。對於 eMMC 設備,這意味著使用安全性擦除或安全性修剪命令。對於 eMMC 4.5 及更高版本,這意味著使用正常的擦除或修剪,然後進行清理操作。
  • 如果底層塊設備不支援BLKSECDISCARD ,則必須改用ioctl(BLKDISCARD) 。在 eMMC 裝置上,這是正常的 Trim 操作。
  • 如果不支援BLKDISCARD ,則可以接受用全零覆蓋塊設備。
  • 最終使用者必須可以選擇要求在刷新分割區之前擦除使用者資料。例如,在 Nexus 裝置上,這是透過fastboot oem lock命令完成的。
  • 設備可以透過efuses或類似機制記錄設備是否已解鎖和/或重新鎖定。

這些要求確保在解鎖操作完成後所有資料都被銷毀。未能實施這些保護措施被視為中等程度的安全漏洞。

隨後可以使用fastboot oem lock指令重新鎖定已解鎖的裝置。鎖定引導程式可以為新的自訂作業系統提供與原始裝置製造商作業系統相同的使用者資料保護(例如,如果裝置再次解鎖,使用者資料將被清除)。