本文已獨(dú)家授權(quán) 郭霖 ( guolin_blog ) 公眾號發(fā)布!
前言:
時(shí)間:2018年3月
涉事對象:Facebook、劍橋分析公司、美國大選
泄露數(shù)據(jù):5000萬用戶數(shù)據(jù)
事件回顧:事件源于Facebook與劍橋分析公司的合作,劍橋分析公司為了學(xué)術(shù)研究,在臉書上創(chuàng)建了一個(gè)應(yīng)用預(yù)測用戶性格喜好的APP用來測試,可是劍橋分析公司不僅收集了用戶的測試結(jié)果,還在未經(jīng)允許地情況下順道收集了5000萬用戶在Facebook上的個(gè)人信息。
劍橋分析公司獲得了5000萬活躍用戶數(shù)據(jù)后,建立起用戶畫像,通過計(jì)算機(jī)對每個(gè)用戶的興趣愛好、性格和行為特點(diǎn)進(jìn)行精確分析,預(yù)測他們的政治傾向。然后定向向用戶推送新聞,借助Facebook的廣告投放系統(tǒng),影響用戶的投票行為。于是,F(xiàn)acebook對美國大選產(chǎn)生了難以推脫的影響。
東窗事發(fā)后,F(xiàn)acebook就被推上輿論風(fēng)口了,外界開始聲討Facebook,雖然此次主要原因不在Facebook,但如果只是把責(zé)任推到劍橋分析公司身上,不從根本上重視用戶隱私保護(hù),F(xiàn)acebook未來還會(huì)遇到第二個(gè)或者第三個(gè)“劍橋分析公司”。
當(dāng)然上面的例子還有很多,談起Android方面的安全機(jī)制、個(gè)人認(rèn)為需要從兩個(gè)方面去討論安全:用戶安全、公司安全。開發(fā)人員需要及時(shí)發(fā)現(xiàn)系統(tǒng)存在的安全隱患,編碼存在的一些問題,及時(shí)修復(fù)安全問題,提高系統(tǒng)安全設(shè)計(jì),保障信息應(yīng)用系統(tǒng)運(yùn)行安全以及用戶的安全。下面就Android應(yīng)用列舉一些安全問題和解決辦法。
問題:RSA加密算法不安全使用帶來的安全風(fēng)險(xiǎn)
RSA加密算法是一種非對稱加密算法。當(dāng)其密鑰長度過短,通常認(rèn)為長度小于512位時(shí),就會(huì)存在較高的被破解風(fēng)險(xiǎn);沒有使用正確的工作模式和填充方式,將會(huì)存在重放攻擊的風(fēng)險(xiǎn)。因RSA加密算法不安全使用造成的加密方法失效,可能造成客戶端隱私數(shù)據(jù)泄露、加密文件破解、傳輸數(shù)據(jù)被獲取、中間人攻擊等后果,導(dǎo)致用戶敏感信息被竊取。
解決方案:
A:使用RSA算法進(jìn)行數(shù)字簽名時(shí),建議密鑰長不要低于512位,推薦1024位
B:使用RSA加密時(shí),如果設(shè)置工作模式為ECB,建議填充方式為OAEPWithSHA256AndMGF1Padding
問題:截屏攻擊風(fēng)險(xiǎn)
截屏攻擊是指在APP運(yùn)行過程中,界面被監(jiān)控并且截屏或者錄屏。截屏攻擊主要發(fā)生在APP登錄、身份認(rèn)證、資金操作等界面。Android5.0中增加了一個(gè)MediaProjection接口,它提供截屏或者錄屏的服務(wù),準(zhǔn)許APP擁有截取屏幕或者記錄系統(tǒng)音頻的能力。同時(shí)系統(tǒng)允許其他消息窗口覆蓋在系統(tǒng)的錄制提示上,從而在用戶無感知的情況下啟動(dòng)錄屏或者截屏工具。通過此方式,攻擊者可以獲取APP關(guān)鍵界面的截圖或者錄像,從而獲取用戶的敏感信息。
解決方案:
在Activity的oncreate()方法中調(diào)用:getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE);或者getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);來達(dá)到防止截屏攻擊的目的。
問題:ZipperDown漏洞
如果大量應(yīng)用會(huì)讀取zip壓縮包進(jìn)行相關(guān)邏輯業(yè)務(wù),常見的場景就是從服務(wù)器下載壓縮包,進(jìn)行資源、代碼熱更新。在解壓zip包時(shí),如果對文件名沒有進(jìn)行限制,通過在文件名加上?../../?前綴的方式,可以將文件解壓到任意路徑。如果攻擊者用遠(yuǎn)程劫持或者本地替換等方式將APP將要加載的正常zip包替換為帶有路徑前綴的惡意zip包,而APP又未對解壓文件的文件名稱進(jìn)行處理,則可能會(huì)出現(xiàn)攻擊者可以對應(yīng)用資源、代碼進(jìn)行任意篡改、替換,從而實(shí)現(xiàn)遠(yuǎn)程代碼劫持等安全問題
解決方案:
1. 對zip包進(jìn)行解壓操作時(shí),在獲取文件名后,添加過濾代碼對文件名中可能包含的 ../ 進(jìn)行過濾判斷。
2. 使用通信協(xié)議加密技術(shù),對通信過程中的數(shù)據(jù)進(jìn)行加密保護(hù),保證數(shù)據(jù)不被篡改。
3. 建議客戶端與服務(wù)端使用加密通道進(jìn)行數(shù)據(jù)交互,并對傳輸數(shù)據(jù)進(jìn)行完整性校驗(yàn),防止zip包被攔截替換。
問題:WebView明文存儲密碼帶來的安全漏洞
WebView組件默認(rèn)開啟了密碼保存功能,會(huì)提示用戶是否保存密碼,當(dāng)用戶選擇保存在WebView中輸入的用戶名和密碼,則會(huì)被明文保存到應(yīng)用數(shù)據(jù)目錄的databases/webview.db中。攻擊者可能通過root的方式訪問該應(yīng)用的WebView數(shù)據(jù)庫,從而竊取本地明文存儲的用戶名和密碼。
解決方案:
開發(fā)者調(diào)用?WebView.getSettings().setSavePassword(false),顯示調(diào)用API設(shè)置為false,讓W(xué)ebView不存儲密碼
問題:WebView遠(yuǎn)程代碼執(zhí)行漏洞
Android API level 17以及之前的系統(tǒng)版本,由于程序沒有正確限制使用addJavascriptInterface方法,遠(yuǎn)程攻擊者可通過使用Java Reflection API利用該漏洞執(zhí)行任意Java對象的方法。通過addJavascriptInterface給WebView加入一個(gè) JavaScript橋接接口,JavaScript通過調(diào)用這個(gè)接口可以直接與本地的Java接口進(jìn)行交互。就有可能出現(xiàn)手機(jī)被安裝木馬程序、發(fā)送扣費(fèi)短信、通信錄或者短信被竊取,甚至手機(jī)被遠(yuǎn)程控制等安全問題
解決方案:
如果一定要使用addJavascriptInterface接口,需使用以下方法:A: 設(shè)置minSdkVersion值大于或等于17,使應(yīng)用不能在4.2以下系統(tǒng)上運(yùn)行;B: 允許被JavaScript調(diào)用的方法必須以@JavascriptInterface進(jìn)行注解聲明。
在在proguard-project文件中有這么一句??
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#? public *;
#}
把注釋解除,把fqcn.of.javascript.interface.for.webview換成你自己定義的那個(gè)類名(包名也必須有,如果定義的是內(nèi)部類,則是cn.wj.ui.WebViewActivity$myInterface),在4.1的系統(tǒng)上是沒有問題了,但4.2的機(jī)子上還是不行,再找找,哦,原來是4.2以上版本調(diào)用js接口需要在方法使用聲明@JavascriptInterface,然后混淆時(shí)可能會(huì)弄丟該聲明導(dǎo)致,程序無法調(diào)用js,需要繼續(xù)再配置文件中添加條件,
-keepattributes *Annotation*
-keepattributes *JavascriptInterface*
問題:動(dòng)態(tài)注冊Receiver風(fēng)險(xiǎn)
使用BroadcastReceiver組件需要?jiǎng)討B(tài)注冊或者靜態(tài)注冊,如果動(dòng)態(tài)注冊廣播,即在代碼中使用registerReceiver()方法注冊BroadcastReceiver,只有當(dāng)registerReceiver()的代碼執(zhí)行到了才進(jìn)行注冊,取消時(shí)則調(diào)用unregisterReceiver()方法。但registerReceiver()方法注冊的BroadcastReceiver是全局的并且默認(rèn)可導(dǎo)出的,如果沒有限制訪問權(quán)限,可以被任意外部APP訪問,向其傳遞Intent來執(zhí)行特定的功能。因此,動(dòng)態(tài)注冊的BroadcastReceive可能會(huì)導(dǎo)致拒絕服務(wù)攻擊、APP數(shù)據(jù)泄漏或是越權(quán)調(diào)用等安全風(fēng)險(xiǎn)
解決方案:
1:在 AndroidManifest.xml 文件中使用靜態(tài)注冊 BroadcastReceiver,同時(shí)設(shè)置 exported="false"。(關(guān)于這個(gè)屬性后面會(huì)說)
2:必須動(dòng)態(tài)注冊 BroadcastReceiver時(shí),使用registerReceiver(BroadcastReceiver,IntentFilter,broadcastPermission,android.os.Handle)函數(shù)注冊。
3:Android8.0新特性想要支持靜態(tài)廣播、需要添加intent.setComponent(new ComponentName()),詳情可以自行查閱
問題:公共組件配置風(fēng)險(xiǎn)
Activity、Service、Provider、Receiver四大組件若配置為android:exported =”true”,將可以被外部應(yīng)用調(diào)用,這樣存在安全隱患的風(fēng)險(xiǎn)。
解決方案:
在應(yīng)用的AndroidManifest.xml文件中,設(shè)置組件的android:exported?屬性為false或者通過設(shè)置自定義權(quán)限來限制對這些組件的訪問。值得一提的是,若部分功能使用前提是配置必須使用exported為true,這種情況開發(fā)者應(yīng)該根據(jù)實(shí)際情況來進(jìn)行集成
問題:用戶敏感信息明文傳輸
用戶在登錄過程中,與服務(wù)器端交互時(shí)明文傳輸用戶名、密碼或者驗(yàn)證碼等,可能會(huì)導(dǎo)致用戶敏感信息暴露。
解決方案:
應(yīng)用與服務(wù)器交互過程中,應(yīng)該對用戶名、密碼、手機(jī)號和驗(yàn)證碼等敏感信息進(jìn)行加密傳輸。
問題:So文件加固檢測
So文件為APK中包含的動(dòng)態(tài)鏈接庫文件,Android利用NDK技術(shù)將C/C++語言實(shí)現(xiàn)的核心代碼編譯為So庫文件供Java層調(diào)用。So文件被破解可能導(dǎo)致應(yīng)用的核心功能代碼和算法泄露。攻擊者利用核心功能與算法可輕易抓取到客戶端的敏感數(shù)據(jù),并對其解密,導(dǎo)致用戶的隱私泄露或直接財(cái)產(chǎn)損失。
解決方案:
對so文件進(jìn)行安全加固、可以使用第三方的安全平臺so加固方案
問題:H5文件加固檢測
應(yīng)用內(nèi)若存在明文存儲的H5資源文件,則會(huì)泄露頁面基本布局和一些重要的信息,如登錄界面、支付界面等。攻擊者可篡改H5資源文件,可能植入釣魚頁面或者惡意代碼,導(dǎo)致用戶賬號、密碼、支付密碼等敏感信息泄露。更有甚者,通過H5代碼暴露相關(guān)活動(dòng)的業(yè)務(wù)邏輯,可能被黑產(chǎn)團(tuán)隊(duì)用來刷紅包、薅羊毛等,造成經(jīng)濟(jì)損失。
解決方案:
可以使用第三方的專業(yè)安全加固方案,對應(yīng)用中的H5文件進(jìn)行加固保護(hù)
問題:Java層代碼動(dòng)態(tài)調(diào)試風(fēng)險(xiǎn)問題
應(yīng)用級配置文件build.gradlel中的調(diào)試標(biāo)記默認(rèn)是開啟,即可以被Java調(diào)試工具如JDB進(jìn)行調(diào)試,但是這樣可能會(huì)出現(xiàn)被獲取和篡改用戶敏感信息,甚至可以分析并且修改代碼實(shí)現(xiàn)的業(yè)務(wù)邏輯,例如竊取用戶密碼、繞過驗(yàn)證碼防護(hù)等。
解決方案:
在應(yīng)用正式發(fā)布前,顯示設(shè)置android:debuggable屬性為false,關(guān)閉Java動(dòng)態(tài)調(diào)試功能、不允許被調(diào)試。
問題:數(shù)據(jù)越權(quán)備份風(fēng)險(xiǎn)
Android 2.1以上的系統(tǒng)可以為APP提供應(yīng)用程序數(shù)據(jù)的備份和恢復(fù)功能,該功能由AndroidMainfest.xml文件中的allowBackup 屬性值控制,其默認(rèn)值為true。當(dāng)該屬性沒有顯式設(shè)置為false時(shí),攻擊者可通過adb backup和adb restore對APP的應(yīng)用數(shù)據(jù)進(jìn)行備份和恢復(fù),從而可能獲取明文存儲的用戶敏感信息,如用戶的密碼、證件號、手機(jī)號、交易密碼、身份令牌、服務(wù)器通信記錄等。利用此類信息攻擊者可偽造用戶身份,盜取用戶賬戶資產(chǎn),或者直接對服務(wù)器發(fā)起攻擊。
解決方案:
將AndroidMainfest.xml文件中的allowBackup屬性值設(shè)置為false來關(guān)閉應(yīng)用程序的備份和恢復(fù)功能;也可以使用專業(yè)安全加固方案的本地?cái)?shù)據(jù)保護(hù)功能,避免本地?cái)?shù)據(jù)泄露。
問題:未移除有風(fēng)險(xiǎn)的WebView系統(tǒng)隱藏接口漏洞
根據(jù)CVE披露的WebView遠(yuǎn)程代碼執(zhí)行漏洞信息(CVE-2012-663、CVE-2014-7224),Android系統(tǒng)中存在一共三個(gè)有遠(yuǎn)程代碼執(zhí)行漏洞的隱藏接口。分別是位于android/webkit/webview中的“searchBoxJavaBridge”接口、android/webkit/AccessibilityInjector.java中的“accessibility”接口和“accessibilityTraversal”接口。調(diào)用此三個(gè)接口的APP在開啟輔助功能選項(xiàng)中第三方服務(wù)的Android系統(tǒng)上將面臨遠(yuǎn)程代碼執(zhí)行漏洞。
解決方案:
如果應(yīng)用內(nèi)使用了WebView組件,那么使用 WebView.removeJavascriptInterface(String name) API時(shí),顯示的移除searchBoxJavaBridge、accessibility、accessibilityTraversal這三個(gè)接口。
問題:日志數(shù)據(jù)泄露風(fēng)險(xiǎn)
調(diào)試信息函數(shù)可能輸出重要的調(diào)試信息,常見的就是Log日志類其中包含的信息可能會(huì)導(dǎo)致用戶信息泄露,泄露核心代碼邏輯等,為發(fā)起攻擊提供便利,例如:Activity的組件名;通信交互的日志;跟蹤的變量值等
解決方案:
應(yīng)用內(nèi)使用統(tǒng)一的Log控制基類,可以靈活的控制Log的輸出打印。(測試環(huán)境允許打印日志、正式環(huán)境不打?。?;或者使用第三方的日志框架
至于常見的代碼混淆、應(yīng)用加固、Http(條件允許)替換成Https等一些基本的安全防護(hù)措施這里就不談了,歡迎補(bǔ)充。
如果這篇文章對您有開發(fā)or學(xué)習(xí)上的些許幫助,希望各位看官留下寶貴的star,謝謝。
Ps:著作權(quán)歸作者所有,轉(zhuǎn)載請注明作者, 商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處(開頭或結(jié)尾請?zhí)砑愚D(zhuǎn)載出處,添加原文url地址),文章請勿濫用、開源項(xiàng)目僅供學(xué)習(xí)交流、也希望大家尊重筆者的勞動(dòng)成果,謝謝。