安卓應用安全指南4.2.3建立/使用廣播接收器高階話題

apachecn_飛龍發表於2018-03-16

4.2.3 建立/使用廣播接收器 高階話題

原書:Android Application Secure Design/Secure Coding Guidebook

譯者:飛龍

協議:CC BY-NC-SA 4.0

4.2.3.1 結合匯出屬性和意圖過濾器設定(用於接收器)

表 4.2-3 展示了實現接收器時,匯出設定和意圖過濾器元素的允許的組合。 下面介紹為什麼原則上禁止使用帶有意圖過濾器定義的exported ="false"

表 4.2-3 可用與否,匯出屬性和意圖過濾器元素的組合

匯出屬性的值
True False
意圖過濾器已定義 OK 不使用
意圖過濾器未定義 OK OK

未指定接收器的匯出屬性時,接收器是否為公共的,取決於該接收器的意圖過濾器的存在與否 [6]。但是,在本手冊中,禁止將匯出的屬性設定為不確定的。 通常,如前所述,最好避免依賴任何給定 API 的預設行為的實現;此外,如果存在明確的方法(如匯出屬性)來啟用重要的安全相關設定,那麼使用這些方法總是一個好主意。

[6] 如果意圖過濾器已定義,接收器是公共的,否則是私有的。更多資訊請參考 https://developer.android.com/guide/topics/manifest/receiver-element.html#exported

即使在相同的應用中將廣播傳送到私有接收器,其他應用中的公共接收器也可能會意外呼叫。 這就是為什麼禁止指定帶有意圖過濾器定義的exported ="false"。 以下兩張圖展示了意外呼叫的發生情況。

圖 4.2-4 是一個正常行為的例子,隱式意圖只能在同一個應用中呼叫私有接收器(應用 A)。 意圖過濾器(在圖中,action ="X")僅在應用 A 中定義,所以這是預期的行為。

圖 4.2-5 是個例子,應用 B 和應用 A 中都定義了意圖過濾器(見圖中的action ="X")的。首先,當另一個應用(應用 C)通過 隱式意圖傳送廣播,它們不被私有接收器(A-1)接收。 所以不會有任何安全問題。 (請參閱圖中的橙色箭頭標記。)從安全形度來看,問題是應用 A 對同一應用中的私有接收器的呼叫。 當應用 A 廣播隱式意圖時,不僅是相同應用中的私有接收器,而且具有相同意圖過濾器定義的公共接收器(B-1)也可以接收意圖。 (圖中的紅色箭頭標記)。 在這種情況下,敏感資訊可能會從應用 A 傳送到 B。當應用 B 是惡意軟體時,會導致敏感資訊的洩漏。 當傳送有序廣播時,它可能會收到意外的結果資訊。

然而,當廣播接收器僅接收由系統傳送的廣播意圖時,應使用帶有意圖過濾器定義的exported="false"。 其他組合不應使用。 這是基於這樣一個事實,即系統傳送的廣播意圖可以通過exported="false"來接收。 如果其他應用傳送的意圖的ACTION與系統傳送的廣播意圖相同,則可能會通過接收它而導致意外行為。 但是,這可以通過指定exported="false"來防止。

4.2.3.2 接收器在啟動應用之前不會被註冊

請務必注意,在AndroidManifest.xml中定義的靜態廣播接收器,在安裝後不會自動啟用 [7]。應用只有在第一次啟動後才能接收廣播;因此,安裝後無法使用接收的廣播作為啟動操作的觸發器。 但是,如果在傳送廣播時設定了Intent.FLAG_INCLUDE_STOPPED_PACKAGES標誌,則即使是尚未第一次啟動的應用也會收到該廣播。

[7] 在 3.0 之前的版本中,接收器可以通過安裝 App 自動啟動。

4.2.3.3 私有廣播接收器可以接收由相同 UID 傳送的廣播

應用

相同的 UID 可以提供給幾個應用。 即使它是私有廣播接收器,也可以接收從 UID 相同的應用傳送的廣播。 但是,這不會是一個安全問題。 由於可以確保 UID 相同的應用具有用於簽署 APK 的一致的開發人員金鑰。 這意味著私有廣播接收器收到的廣播,只是從內部應用傳送的廣播。

4.2.3.4 廣播的型別和特性

根據是否有序以及是否粘滯的組合,廣播有四種型別。 要傳送的廣播型別基於廣播傳送方法而確定。 請注意,粘性廣播在 Android 5.0(API Level 21)中已棄用。

型別 傳送方法 是否有序 是否粘性
普通 sendBroadcast()
有序 sendOrderedBroadcast()
粘性 sendStickyBroadcast()
粘性有序 sendStickyOrderedBroadcast()

每個廣播型別的特性描述如下:

型別 特性
普通 普通廣播傳送到可接收的廣播接收器時消失。 廣播由多個廣播接收器同時接收。 這與有序廣播有所不同。 廣播被允許由特定的廣播接收機接收。
有序 有序廣播的特點是,可接收的廣播接收器依次接收廣播。 優先順序較高的廣播接收器較早收到。 當廣播被傳送到所有廣播接收器或廣播接收器呼叫abortBroadcast(),廣播將消失。 廣播被允許由宣告瞭特定許可權的廣播接收器接收。 另外,廣播接收器傳送的結果資訊,可以由傳送者使用有序廣播接收。 SMS 接收通知的廣播(SMS_RECEIVED)是有序廣播的代表性示例。
粘性 粘性廣播不會消失並保留在系統中,然後呼叫registerReceiver()的應用可以稍後接收粘性廣播。 由於粘性廣播與其他廣播不同,它不會自動消失。 因此,當不需要粘性廣播時,需要顯式呼叫removeStickyBroadcast()來刪除粘滯廣播。 此外,帶有特定許可權的受限的廣播接收器無法接收廣播。 電池狀態變化通知的廣播(ACTION_BATTERY_CHANGED)是粘性廣播的代表性示例。
粘性有序 這是具有有序和粘性特徵的廣播。 與粘性廣播相同,它不能僅僅允許帶有特定許可權的廣播接收器接收廣播。

從廣播特性行為的角度來看,上表反過來排列在下面的表中。

廣播的特徵行為 普通 有序 粘性 粘性有序
由許可權限制的廣播接收器可以接收廣播 OK OK
從廣播接收器獲得過程結果 OK OK
使廣播接收器按順序處理廣播 OK OK
稍後收到已經傳送的廣播 OK OK

4.2.3.5 廣播資訊可能輸出到LogCat

傳送/接收的廣播基本上不會輸出到LogCat。 然而,缺少許可權導致接收/傳送方的錯誤時,將輸出錯誤日誌。 由廣播傳送的意圖資訊包含在錯誤日誌中,因此在發生錯誤之後,需要注意,傳送廣播時,意圖的資訊顯示在LogCat中。

傳送方的缺少許可權的錯誤:

W/ActivityManager(266): Permission Denial: broadcasting Intent { act=org.jssec.android.broadcastreceive
r.creating.action.MY_ACTION } from org.jssec.android.broadcast.sending (pid=4685, uid=10058) requires o
rg.jssec.android.permission.MY_PERMISSION due to receiver org.jssec.android.broadcastreceiver.creating/
org.jssec.android.broadcastreceiver.creating.CreatingType3Receiver

接收方的缺少許可權的錯誤:

W/ActivityManager(275): Permission Denial: receiving Intent { act=org.jssec.android.broadcastreceiver.c
reating.action.MY_ACTION } to org.jssec.android.broadcastreceiver.creating requires org.jssec.android.p
ermission.MY_PERMISSION due to sender org.jssec.android.broadcast.sending (uid 10158)

4.2.3.6 在主螢幕放置應用的快捷方式時,需要注意的東西

在下面的內容中,我們討論了建立快捷方式時的一些需要注意的東西,它們用於從主螢幕啟動應用,或者用於建立 URL 快捷方式,例如 Web 瀏覽器中的書籤。 作為一個例子,我們考慮如下所示的實現。

在主螢幕放置應用的快捷方式:

Intent targetIntent = new Intent(this, TargetActivity.class);

// Intent to request shortcut creation

Intent intent = new Intent("com.android.launcher.action.INSTALL_SHORTCUT");
// Specify an Intent to be launched when the shortcut is tapped
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, targetIntent);
Parcelable icon = Intent.ShortcutIconResource.fromContext(context, iconResource);
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, icon);
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, title);
intent.putExtra("duplicate", false);

// Use Broadcast to send the system our request for shortcut creation
context.sendBroadcast(intent);

在由上面的程式碼片段傳送的廣播中,接收器是主螢幕應用,並且很難識別包名; 我們必須謹慎記住,這是一個向公共接收器傳遞的隱式意圖。 因此,此片段傳送的廣播,可以被任何任意應用接收,包括惡意軟體;因此,在意圖中包含敏感資訊可能會造成資訊洩漏的風險。 特別重要的是要注意,在建立基於 URL 的快捷方式時,祕密資訊可能包含在 URL 本身中。

作為對策,有必要遵循“4.2.1.2 公共廣播接收器 – 接收/傳送廣播”中列出的要點,並確保傳輸的意圖不包含敏感資訊。


相關文章