OWASP 類別:MASVS-PLATFORM:平台互動
總覽
Android 應用程式和 Android 系統可以使用廣播訊息做為傳訊系統,如果其他應用程式有可能感興趣的事件,就會收到該系統的通知。「固定式廣播訊息」是一種特殊的廣播訊息,系統會在訊息播送完成後,將已傳送的意圖物件保留在快取中。此外,系統可能會將固定式意圖重新播送給日後註冊的接收器。遺憾的是,固定式廣播訊息 API 存在許多與安全性相關的缺點,因此在 Android 5.0 (API 級別 21) 中已遭淘汰。
任何人皆可存取固定式廣播訊息
系統無法僅針對擁有特定權限的接收器播送固定式廣播訊息,因此這類訊息不適合用於播送機密資訊。您可能會以為在廣播訊息 Intent
中指定應用程式套件名稱,就能限制 BroadcastReceivers
的組合,但其實不是這樣:
Kotlin
val intent = Intent("com.example.NOTIFY").apply {
setPackage("com.example.myapp")
}
applicationContext.sendBroadcast(intent)
Java
Intent intent = new Intent("com.example.NOTIFY");
intent.setPackage("com.example.myapp");
getApplicationContext().sendBroadcast(intent);
在此示例中,只有 com.example.myapp
套件中的接收器,才能在廣播訊息傳送時收到意圖。不過,如果是從固定式快取重新播送 Intent,系統就不會套用套件名稱篩選器。而當您使用 registerReceiver()
方法註冊接收器時,無論接收器所在套件的名稱為何,系統都會重新將固定式快取中符合指定篩選器的所有意圖播送給接收器。
任何人皆可傳送固定式廣播訊息
如要傳送固定式廣播訊息,應用程式只須具備 android.permission.BROADCAST_STICKY
權限即可,系統會在安裝應用程式時自動授予這項權限。因此,攻擊者可以傳送任何意圖給任何接收器,這樣即使未經授權,他們也可能存取其他應用程式的。廣播接收器則可將傳送者限定為擁有特定權限的傳送者。不過這麼一來,該接收器就無法接收來自固定式快取的廣播訊息,因為這類訊息不會在任何應用程式的識別環境中傳送,也不會使用任何權限播送。
任何人皆可修改固定式廣播訊息
當固定式廣播訊息內含意圖時,該意圖會取代先前在固定式快取中具有相同動作、資料、類型、ID、類別和分類的所有例項。因此,攻擊者可以透過合法的應用程式,輕易覆寫固定式意圖內的額外資料,而這些資料可能會重新播送至其他接收器。
使用 sendStickyOrderedBroadcast()
方法傳送的廣播訊息一次會傳送給一個接收器,讓優先順序較高的接收器先行使用廣播訊息,然後再傳送給優先順序較低的接收器。由於每個接收器會按順序執行,因此可將結果傳播至下一個接收器 (例如透過呼叫 setResultData()
),也可以取消播送,防止後續的接收器接收廣播訊息。如果攻擊者能透過合法應用程式接收排定順序的固定式廣播訊息,可能會建立高優先順序的接收器,藉此竄改廣播訊息的結果資料或完全停止播送。
影響
影響有很多種,具體取決於固定式廣播訊息的使用方式,以及要將哪些資料傳遞給廣播接收器。一般來說,使用固定式廣播訊息可能導致機密資料外洩、資料遭竄改、在未經授權情況下執行其他應用程式的行為,以及阻斷服務攻擊。
因應措施
請勿使用固定式廣播訊息。建議您搭配本機資料庫等其他機制使用非固定式廣播訊息,視需要擷取目前的值。
開發人員可以透過權限,或是在意圖上設定應用程式套件名稱,控制哪些人可以接收非固定式廣播訊息。此外,如果不需要將廣播訊息傳送給應用程式以外的元件,請使用會執行觀測器模式的 LiveData
。
如要進一步瞭解如何保護廣播訊息,請參閱「廣播總覽」頁面。