Android 12 已來(lái)规辱,你的 App 崩潰了嗎? 我們已經(jīng)開(kāi)始做 Android 12 的適配了栽燕,在 Android 12 中包含了很多的功能和一些行為的變更罕袋,接下來(lái)我們一起來(lái)分析這些行為的變更對(duì)我們的應(yīng)用產(chǎn)生了那些影響。
通過(guò)這篇文章你將學(xué)習(xí)到以下內(nèi)容:
- 為什么在 Android 12 上需要顯示聲明
android:exported
屬性碍岔? - 為什么在 Android 12 上需要顯示指定 PendingIntent 的可變性浴讯?
- 為什么在 Android 12 上限制 adb 備份的默認(rèn)行為?
- 如何檢查 App 的安全漏洞付秕?
android:exported 屬性
在 Android 12 中包含 <intent-filter>
的 activity
兰珍、 service
或 receiver
必須為這些應(yīng)用組件顯示聲明 android:exported
屬性,如下所示询吴。
<activity
android:name=".TestActivity"
android:exported="false">
<intent-filter>
......
</intent-filter>
</activity>
如果在包含 <intent-filter>
的 activity
掠河、 service
或 receiver
組件中,沒(méi)有顯示聲明 android:exported
的值猛计,你的應(yīng)用將無(wú)法安裝唠摹,錯(cuò)誤日志如下所示。
Installation did not succeed.
The application could not be installed: INSTALL_FAILED_VERIFICATION_FAILURE
List of apks:
[0] '.../build/outputs/apk/debug/app-debug.apk'
Installation failed due to: 'null'
如果您的應(yīng)用在需要聲明 android:exported
的值時(shí)未進(jìn)行此聲明奉瘤,錯(cuò)誤日志如下所示勾拉。
Targeting S+ (version 10000 and above) requires that an explicit value for \
android:exported be defined when intent filters are present
如果對(duì)上面的異常產(chǎn)生的條件煮甥,不是很理解,可以點(diǎn)擊下方鏈接查看藕赞,目前已經(jīng)有很多開(kāi)源項(xiàng)目都已經(jīng)開(kāi)始適配這個(gè)行為的變更了成肘,例如 leakcanary
等等,詳情前往查看下列地址:
- Update launcher activity attribute to Android 12
- Declared android:exported explicitly for components with intent-filter. Android 12 requirement
這個(gè)行為的變更無(wú)論是對(duì)庫(kù)開(kāi)發(fā)者 和 還是應(yīng)用開(kāi)發(fā)者影響都非常大斧蜕。
為什么在 Android 12 上需要顯示聲明 android:exported 屬性
android:exported
屬性的默認(rèn)值取決于是否包含 <intent-filter>
双霍,如果包含 <intent-filter>
那么默認(rèn)值為 true,否則 false批销。
- 當(dāng)
android:exported="true"
時(shí)洒闸,如果不做任何處理,可以接受來(lái)自其他 App 的訪問(wèn) - 當(dāng)
android:exported="false"
時(shí)均芽,限制為只接受來(lái)自同一個(gè) App 或一個(gè)具有相同user ID
的 App 的訪問(wèn)
正因?yàn)?android:exported
的屬性的默認(rèn)值的問(wèn)題丘逸,Twicca App 發(fā)生過(guò)一次安全性問(wèn)題,因?yàn)榱硪粋€(gè)沒(méi)有訪問(wèn) SD 卡或網(wǎng)絡(luò)權(quán)限的 App掀宋,可以通過(guò) Twicca App 將存儲(chǔ)在 SD 卡上的圖片或電影上傳到 Twicca 用戶的 Twitter 賬戶上的社交網(wǎng)絡(luò)上深纲。
產(chǎn)生問(wèn)題的代碼如下所示:
<activity android:configChanges="keyboard|keyboardHidden|orientation" android:name=".media.yfrog.YfrogUploadDialog" android:theme="@style/Vulnerable.Dialog" android:windowSoftInputMode="stateAlwaysHidden">
<intent-filter android:icon="@drawable/yfrog_icon" android:label="@string/YFROG">
<action android:name="jp.co.vulnerable.ACTION_UPLOAD" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
<data android:mimeType="video/*" />
</intent-filter>
</activity>
因?yàn)樘砑恿?intent-filter
所以 android:exported
的屬性的默認(rèn)值為 true,因此可以接受來(lái)自其他 App 的訪問(wèn)布朦,進(jìn)而造成了上述問(wèn)題(通過(guò) Twicca App 將存儲(chǔ)在 SD 卡上的圖片或電影上傳到 Twicca 用戶的 Twitter 賬戶上的社交網(wǎng)絡(luò)上)囤萤,而解決方案有兩個(gè):
- 方案一:添加
android:exported="false"
屬性
<activity android:exported="false" android:configChanges="keyboard|keyboardHidden|orientation" android:name=".media.yfrog.YfrogUploadDialog" android:theme="@style/ VulnerableTheme.Dialog" android:windowSoftInputMode="stateAlwaysHidden" >
</activity>
- 方案二: Twicca App 沒(méi)有使用方式一,而是檢查調(diào)用者的包名是否與自身的包名相同
public void onCreate(Bundle arg5) {
super.onCreate(arg5);
...
ComponentName v0 = this.getCallingActivity();
if(v0 == null) {
this.finish();
} else if(!jp.r246.twicca.equals(v0.getPackageName())) {
this.finish();
} else {
this.a = this.getIntent().getData();
if(this.a == null) {
this.finish();
}
...
}
}
}
這種方案也是可行的是趴,因?yàn)樵谝慌_(tái)設(shè)備上涛舍,不可能會(huì)出現(xiàn)兩個(gè)包名相同的應(yīng)用,更多詳細(xì)的信息可以前往查看 Restrict access to sensitive activities唆途。
這僅僅是關(guān)于 activity
的安全漏洞的其中一個(gè)富雅,在不同的場(chǎng)景下利用這些漏洞做的事情也可能不一樣。當(dāng)然還有 service
和 receiver
組件也都是一樣肛搬,存在安全性問(wèn)題没佑。
指定 PendingIntent 的可變性
在 Android 12 中創(chuàng)建 PendingIntent 的時(shí)候,需要顯示的聲明是否可變温赔,請(qǐng)分別使用 PendingIntent.FLAG_MUTABLE
或 PendingIntent.FLAG_IMMUTABLE
標(biāo)志蛤奢,如果您的應(yīng)用試圖在不設(shè)置任何可變標(biāo)志的情況下創(chuàng)建 PendingIntent 對(duì)象,系統(tǒng)會(huì)拋出 IllegalArgumentException
異常陶贼,錯(cuò)誤日志如下所示啤贩。
PACKAGE_NAME: Targeting S+ (version 10000 and above) requires that one of \
FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.
Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if \
some functionality depends on the PendingIntent being mutable, e.g. if \
it needs to be used with inline replies or bubbles.
為什么在 Android 12 上需要顯示的指定 PendingIntent 的可變性
在 Adnroid 12 之前,默認(rèn)創(chuàng)建一個(gè) PendingIntent 它是可變的拜秧,因此其他惡意應(yīng)用程序可能會(huì)攔截痹屹,重定向或修改此 Intent。(但是是有條件限制的)
一個(gè) PendingIntent 是一個(gè)可以給另一個(gè)應(yīng)用程序使用的 Intent枉氮,PendingIntent 接收待處理意圖的應(yīng)用程序可以使用與產(chǎn)生待處理意圖的應(yīng)用程序相同的權(quán)限和身份執(zhí)行待處理意圖中指定的操作志衍。
因此暖庄,創(chuàng)建待處理意圖時(shí)必須小心,為了安全性 Google 在 Android 12 中需要開(kāi)發(fā)者自己來(lái)指定 PendingIntent 的可變性楼肪。
更多關(guān)于 PendingIntent 安全性介紹培廓,可以前往查看 Always pass explicit intents to a PendingIntent。
adb 備份限制
Android 開(kāi)發(fā)者都應(yīng)該知道這個(gè)命令 adb backup
, 它可以備份應(yīng)用的數(shù)據(jù)春叫,在 Android 12 中医舆,為了保護(hù)私有應(yīng)用數(shù)據(jù),用戶運(yùn)行 adb backup
命令時(shí)象缀,從設(shè)備導(dǎo)出的任何其他系統(tǒng)數(shù)據(jù)都不包含應(yīng)用數(shù)據(jù)。
如果你在測(cè)試和開(kāi)發(fā)過(guò)程中需要使用 adb backup
來(lái)備份應(yīng)用數(shù)據(jù)爷速,你可以在 AndroidManifest 中將 android:debuggable
設(shè)置為 true 來(lái)導(dǎo)出應(yīng)用數(shù)據(jù)央星。
<application
android:name=".App"
android:debuggable="true"
....../>
注意:在發(fā)布應(yīng)用前將 android:debuggable 設(shè)置為 false。
為什么在 Android 12 上限制了 adb backup
命令的默認(rèn)行為
因?yàn)檫@個(gè)存在嚴(yán)重的安全問(wèn)題惫东,當(dāng)初 Google 為了提供 App 數(shù)據(jù)備份和恢復(fù)功能莉给,可以在 AndroidManifest 中添加 android:allowBackup
屬性,默認(rèn)值為 true, 當(dāng)你創(chuàng)建一個(gè)應(yīng)用的時(shí)候廉沮,會(huì)默認(rèn)添加這個(gè)屬性颓遏,如下所示。
<application
android:name=".App"
android:allowBackup="true"
....../>
當(dāng) android:allowBackup="true"
時(shí)滞时,用戶可以通過(guò) adb backup
和 adb restore
命令對(duì)應(yīng)用數(shù)據(jù)進(jìn)行備份和恢復(fù)叁幢,也就是說(shuō)可以在其他的 Android 手機(jī)上安裝同一個(gè)應(yīng)用,通過(guò)如上命令恢復(fù)用戶的數(shù)據(jù)坪稽。
為了安全起見(jiàn)曼玩,我們?cè)诎l(fā)布出去的 Apk 中一定要將 android:allowBackup
屬性設(shè)置為 false 來(lái)關(guān)閉應(yīng)用程序的備份和恢復(fù)功能,以免造成信息泄露窒百。國(guó)民級(jí)應(yīng)用 XX 信, 在曾今發(fā)出的版本中 allowBackup 的屬性值是 true黍判,被其他逆向開(kāi)發(fā)者利用之后,現(xiàn)在的版本中這個(gè)值已經(jīng)修改為 false了篙梢,有興趣的小伙們可以反編譯看看顷帖。
如何檢查 App 的安全漏洞
在這里推薦一個(gè)開(kāi)源項(xiàng)目 linkedin/qark 這是由 LinkedIn 開(kāi)源的項(xiàng)目,這個(gè)工具被設(shè)計(jì)用來(lái)尋找與安全相關(guān)的 Android 應(yīng)用程序漏洞渤滞,無(wú)論是源代碼還是打包的 APK贬墩,具體的用法文檔上寫(xiě)的非常的清楚了,這里不做詳細(xì)的介紹了蔼水。
這個(gè)開(kāi)源項(xiàng)目的檢查結(jié)果震糖,作為參考即可。當(dāng)然也有很多公司花了重金去購(gòu)買第三方的服務(wù)來(lái)檢查 App 的安全漏洞趴腋。
在 Android 12 上這幾個(gè)行為的變更它們都有一個(gè)共性:安全性吊说,可見(jiàn) Google 這幾年在安全上做了很多的努力论咏,當(dāng)然還有其他的一些行為的變更,可以前往查看 行為變更:以 Android 12 為目標(biāo)平臺(tái)的應(yīng)用颁井。
參考文章
- 行為變更:以 Android 12 為目標(biāo)平臺(tái)的應(yīng)用
- Update launcher activity attribute to Android 12
- Declared android:exported explicitly for components with intent-filter. Android 12 requirement
- confluence
如果有幫助 點(diǎn)個(gè)贊 就是對(duì)我最大的鼓勵(lì)
最后推薦長(zhǎng)期更新和維護(hù)的項(xiàng)目:
個(gè)人博客厅贪,將所有文章進(jìn)行分類,歡迎前去查看 https://hi-dhl.com
KtKit 小巧而實(shí)用雅宾,用 Kotlin 語(yǔ)言編寫(xiě)的工具庫(kù)养涮,歡迎前去查看 KtKit
計(jì)劃建立一個(gè)最全、最新的 AndroidX Jetpack 相關(guān)組件的實(shí)戰(zhàn)項(xiàng)目 以及 相關(guān)組件原理分析文章眉抬,正在逐漸增加 Jetpack 新成員贯吓,倉(cāng)庫(kù)持續(xù)更新,歡迎前去查看 AndroidX-Jetpack-Practice
LeetCode / 劍指 offer / 國(guó)內(nèi)外大廠面試題 / 多線程 題解蜀变,語(yǔ)言 Java 和 kotlin悄谐,包含多種解法、解題思路库北、時(shí)間復(fù)雜度爬舰、空間復(fù)雜度分析
近期必讀熱門文章
- Android 進(jìn)化史 1.0 到 12 ,還記得第一次使用是哪個(gè)版本寒瓦?
- LinkedList 落幕了嗎情屹?
- Oracle 官方推薦,使用 ReentrantLock 需要注意的細(xì)節(jié)
- Kotlin 宣布一個(gè)重磅特性
- Google 宣布廢棄 LiveData.observe 方法
- 使用 kotlin 需要注意的一個(gè)細(xì)節(jié)
- 影響性能的 Kotlin 代碼(一)
- Jetpack Splashscreen 解析 | 助力新生代 IT 農(nóng)民工 事半功倍
- 為數(shù)不多的人知道的 Kotlin 技巧及解析(三)
- 為數(shù)不多的人知道的 Kotlin 技巧以及 原理解析(二)
- 為數(shù)不多的人知道的 Kotlin 技巧以及 原理解析(一)
- 揭秘 Kotlin 中的 == 和 ===
- Kotlin 密封類進(jìn)化了
- Kotlin 中的密封類 優(yōu)于 帶標(biāo)簽的類
- Kotlin Sealed 是什么杂腰?為什么 Google 都在用
- Android 12 行為變更垃你,對(duì)應(yīng)用產(chǎn)生的影響
- 圖解多平臺(tái) AndroidStudio 技巧(三)