Android應用安全開發之元件安全淺談

語言: CN / TW / HK

總篇134篇 2022年第9篇

前言

本文主要講述在android開發過程中如何更安全地使用元件,瞭解元件使用過程中需要關注的風險點,提高原始碼的可靠性和應用系統自身的安全防護能力。

01

背景

Android開發的四大元件包含Activity(活動)、Service(服務)、BroadcastReceive(廣播)、ContentProvider(內容提供),每個元件都可以在AndroidManifest中通過android:exported屬性設定為公有或私有。

Activity、Service、BroadcastReceiver在預設沒有設定exported屬性的情況下,元件在制定Intent過濾器(intent-filter)後預設也是公有元件。

ContentProvider 元件在api level 17以下的所有應用中android:exported屬性預設值為true(公有),17及以上預設值為false(私有)。

所有公有元件都可以被外部程式呼叫,這就意味著容易被外部惡意程式攻擊。

02

元件安全開發

1、刪除AndroidManifest中未實現

若開發人員在manifest 檔案中定義了公有元件,但元件沒有程式碼實現,則攻擊者可通過呼叫未實現的元件進行攻擊導致APP崩潰。

2、非必要匯出元件不匯出

不需要被外部程式呼叫的元件應該新增android:exported=”false”屬性,這個屬性說明它是私有的,只有同一個應用程式的元件或帶有相同使用者ID的應用程式才能呼叫。

3、設定特定元件的訪問許可權

對於希望能夠被特定的外部程式訪問的元件,可以為其設定訪問許可權。

首先需要自定義permission,並設定protectionLevel。

<permission android:name="com.autohome.permission_test" 
android:protectionLevel="signature"/>

android:protectionLevel引數說明

屬性

描述

normal

預設值, 低風險許可權, 在安裝的時候, 系統會自動授予許可權

dangerous

高風險許可權, 如發簡訊, 打電話, 讀寫通訊錄。使用此 protectionLevel 來標識使用者可能關注的一些許可權。 Android 將會在安裝程式時, 警示使用者關於這些許可權的需求

signature

簽名許可權, 當應用程式所用簽名與宣告引許可權的應用程式所用簽名相同時, 才能將許可權授給它

signatureOrSystem

除了具有相同簽名的 APP 可以訪問外, Android 系統中的程式也有許可權訪問

元件新增許可權:這樣宣告的Activity在被呼叫時,Android就會檢查呼叫者是否具有com.autohome.permission_test許可權,如果沒有就會觸發SecurityException異常。

<activity  
android:name="DemoActivity"
android: permission=”com.autohome.permission_test”
<intent-filter>
...
</intent-filter>
</activity>

若想呼叫該activity的許可權,則需要在app的Mainifest檔案中使用自定義的許可權。

<uses-permissionandroid:name="com.autohome.permission_test"/>

4、安全啟動私有元件

正常情況下一個私有元件是安全的,但是當私有元件能夠被一個公有元件啟動的話,此時該私有元件將不再安全。

私有元件A,和一個公有元件B。如果B能夠根據從外傳入的Intent中的內容開啟私有元件A,同時私有元件A的Intent的內容來自啟動匯出元件B的Intent的內容,那麼攻擊者就可以通過對外匯出元件B,去控制私有匯出元件A。這就可能會造成嚴重的安全風險。

5、使用LocalBroadcastManager來實現BroadcastReceiver動態註冊

BroadcastReceiver元件的註冊方式可分為兩種,一種是靜態註冊,即提前在AndroidManifest.xml檔案中宣告元件;另外一種是動態註冊,即在程式碼中使用registerReceiver()方法註冊BroadcastReceiver,只有當registerReceiver()的程式碼執行到了才進行註冊,取消時則呼叫unregisterReceiver()方法。而容易被忽略的是registerReceiver()方法註冊的是全域性BroadcastReceiver,在其生命週期裡是預設可匯出的,如果沒有指定許可權訪問控制,可以被任意外部應用訪問,向其傳遞Intent來執行特定的功能。

開發者可使用LocalBroadcastManager來實現BroadcastReceiver動態註冊,保證資料傳遞僅限於應用內。

public static void sendLocalBroadcast(Intent intent) {
LocalBroadcastManager.getInstance(getInstance()).sendBroadcastSync(intent);
}
public static void registerLocalReceiver(BroadcastReceiver receiver, IntentFilter filter) {
LocalBroadcastManager.getInstance(getInstance()).registerReceiver(receiver, filter);

public static void unregisterLocalReceiver(BroadcastReceiver receiver) {
LocalBroadcastManager.getInstance(getInstance()).unregisterReceiver(receiver);
}


6、防止ContentProvider 檔案目錄遍歷

對外暴露的Content Provider實現了openFile()介面,因此其他有相應呼叫該Content Provider許可權的應用即可呼叫Content Provider的openFile()介面進行檔案資料訪問。但是如果沒有進行Content Provider訪問許可權控制和對訪問的目標檔案的Uri進行有效判斷,攻擊者利用檔案目錄遍歷可訪問任意可讀檔案,更有甚者可以往手機裝置可寫目錄中寫入任意資料。

如果應用的Content Provider元件沒有必要實現openFile()介面,去除沒有必要的openFile()介面。

如果必要實現openFile()介面,對提交的引數進行“../”目錄跳轉符或其他安全校驗。

7、intent引數校驗

Intent通常用於Activity、Service、Broadcast Receiver等元件之間進行資訊傳遞。收到intent傳遞的資料,元件應該驗證並謹慎處理,避免執行惡意命令,或因資料格式錯誤,導致APP崩潰。

03

總結

1、對不必要匯出的元件設定android:exported屬性為false。

2、需要匯出的元件,進行許可權控制。

3、公有元件啟動私有元件時,需嚴格校驗intent傳入的引數。

4、使用LocalBroadcastManager來發送本地廣播。

作者簡介

汽車之家

李麗

雲平臺部

2018年9月入汽車之家智慧資料中心雲平臺部,主要負責資訊保安運營平臺的開發、移動APP安全檢測、敏感資料治理等相關工作。

閱讀更多

▼ 關注「 之家技術 」,獲取更多技術乾貨