Android安全——客戶端安全要點
一、前言:
近期facebook的隱私泄露事件再度喚起了公眾對隱私的關注,在這個越來越重視個人隱私的時代里,安全早已是一個無法繞開的話題。
作為一個開發人員,必須具備安全意識,掌握基礎的安全知識,為打造更加安全的應用做出努力。本文淺談Android客戶端的安全問題,涉及組件、WebView、存儲、傳輸、日誌、混淆、應用加固等安全漏洞及防護策略,運用更加合理的配置與防護措施來提高應用的安全級別。
二、組件安全:
規範安卓標準組件(Activity、Service、Receiver、Provider)的訪問許可權。
這裡提到的組件訪問許可權主要是指跨應用的進程間通信(IPC,Inter-Process Communication),開發者可以限定應用內的組件是否允許被其他應用調起,或接收來自外部應用的數據,或者訪問我們的數據。並且必須對來自外部應用的數據做校驗處理,避免來自外部攻擊。如惡意調用組件、廣播數據攻擊、惡意訪問數據等等。
1、設置許可權開放屬性:
android:exported=["true" | "false"]
該屬性為四大組件共有屬性,其中含義大同小異。默認值由其包含 <intent-filter>
與否決定。若未包含,則默認為「false」,若存在至少一個,則默認值為「true」。
- 在Activity中:表示是否允許外部應用組件啟動。若為「false」,則 Activity 只能由同一應用或同一用戶 ID 的不同應用啟動。
- 在Service中:表示是否允許外部應用組件調用服務或與其進行交互。若為「false」,則 Activity 只能由同一應用或同一用戶 ID 的不同應用啟動。
- 在Receiver中:表示是否可以接收來自其應用程序之外的消息,如來自系統或或其他應用的廣播。若為「 false」,則廣播接收器只能接收具有相同用戶ID的相同應用程序或應用程序的組件發送的消息。
- 在Provider中:表示是否允許其他應用程序訪問內容提供器。若為「false」,則具有與Provider相同的用戶ID(UID)的應用程序才能訪問它。如果需要給其他應用程序提供內容,則應當限定讀寫許可權。
2、配置自定義許可權
在AndroidManifest.xml
中定義一個名稱為com.fedming.demo.ACCESS
的許可權:
<permission android:description="string resource" android:icon="drawable resource" android:label="string resource" android:name="com.fedming.demo.ACCESS" android:permissionGroup="string resource" android:protectionLevel=["normal" | "dangerous" | "signature" | ...] />
android:protectionLevel="signature"
表示簽名保護級別,「簽名」級別許可權的內容對用戶完全透明開放,而且只有由執行許可權檢查的應用的開發者簽名的應用才可訪問這些內容。
應用到四大組件或者Application中android:permission="com.fedming.demo.ACCESS"
,即可實現對非同一簽名應用的限制性訪問。一般用於一些內部應用之間共享的私有組件。
使用更加安全高效的LocalBroadcastManager
區別基於Binder實現的BroadcastReceiver,LocalBroadcastManager 是基於Handler實現的,擁有更高的效率與安全性。安全性主要體現在數據僅限於應用內部傳輸,避免廣播被攔截、偽造、篡改的風險。簡單了解下用法:
- 自定義BroadcastReceiver
public class MyReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //Do SomeThing Here }}
- 註冊Receiver
MyReceiver myReceiver = new MyReceiver();LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this);IntentFilter filter = new IntentFilter();filter.addAction("MY_ACTION");localBroadcastManager.registerReceiver(myReceiver, filter);
- 發送本地廣播
Bundle bundle = new Bundle();bundle.putParcelable("DATA", content);Intent intent = new Intent();intent.setAction("MY_ACTION");intent.putExtras(bundle);LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
- 在Activity銷毀時取消註冊
@Override protected void onDestroy() { super.onDestroy(); localBroadcastManager.unregisterReceiver(myReceiver); }
Application相關屬性配置
1、debugable屬性
android:debuggable=["true" | "false"]
很多人說要在發布的時候手動設置該值為false
,其實根據官方文檔說明,默認值就是false
。
2、allowBackup屬性
android:allowBackup=["true" | "false"]
設置是否支持備份,默認值為true
,應當慎重支持該屬性,避免應用內數據通過備份造成的泄漏問題。
三、WebView安全
1、謹慎支持JS功能,避免不必要的麻煩。
提到對於Android4.2以下的JS任意代碼執行漏洞,Android4.2以下?不必支持了吧!
2、請使用https的鏈接
第一是安全;第二是避免被噁心的運營商劫持,插入廣告,影響用戶體驗。
3、處理file協議安全漏洞
//若不需支持,則直接禁止 file 協議setAllowFileAccess(false);setAllowFileAccessFromFileURLs(false);setAllowUniversalAccessFromFileURLs(false);
4、密碼明文保存漏洞
由於webView默認開啟密碼保存功能,所以在用戶輸入密碼時,會彈出提示框,詢問用戶是否保存。若選擇保存,則密碼會以明文形式保存到 /data/data/com.package.name/databases/webview.db
中,這樣就有被盜取密碼的危險。所以我們應該禁止網頁保存密碼,設置WebSettings.setSavePassword(false)
5、開啟安全瀏覽模式
<manifest> <meta-data android:name="android.webkit.WebView.EnableSafeBrowsing" android:value="true" /> <application> ... </application> </manifest>
啟用安全瀏覽模式後,WebView 將參考安全瀏覽的惡意軟體和釣魚網站資料庫檢查訪問的 URL ,在用戶打開之前給予危險提示,體驗類似以於Chrome瀏覽器。
四、數據存儲安全;
1、秘鑰及敏感信息
此類配置應當妥善存放,不要在類中硬編碼敏感信息,可以使用JNI將敏感信息寫到Native層。
2、SharePreferences
首先不應當使用SharePreferences來存放敏感信息。存儲一些配置信息時也要配置好訪問許可權,如私有的訪問許可權 MODE_PRIVATE,避免配置信息被篡改。
3、簽名配置signingConfigs
避免明文保存簽名密碼,可以將密碼保存到本地,無需上傳版本控制系統
在app目錄下建立一個不加入版本控制系統的gradle.properties
文件:
STORE_PASSWORD = qwer1234KEY_PASSWORD = demo1234KEY_ALIAS = demokey
gradle將自動引入gradle.properties
文件,可以直接在buld.gradle
文件中使用:
signingConfigs { release { try { storeFile file("E:FDMKeydemo.jks") storePassword STORE_PASSWORD keyAlias KEY_ALIAS keyPassword KEY_PASSWORD }catch (ex) { throw new InvalidUserDataException("You should define KEYSTORE_PASSWORD and KEY_PASSWORD in gradle.properties.") } }}
五、數據傳輸安全
1、使用HTTPS協議
HTTPS的主要思想是在不安全的網路上創建一安全信道,並可在使用適當的加密包和伺服器證書可被驗證且可被信任時,對竊聽和中間人攻擊提供合理的防護。可以說是非常基礎的安全防護級別了。
2、Android網路安全性配置
該特性讓應用可以在一個安全的聲明性配置文件中靈活的自定義其網路安全設置,而無需修改應用代碼,滿足更高的安全性要求。
在AndroidManifest.xml中配置networkSecurityConfig:
<?xml version="1.0" encoding="utf-8"?><manifest ... > <application android:networkSecurityConfig="@xml/network_security_config" ... > ... </application></manifest>
network_security_config文件如下:
<?xml version="1.0" encoding="utf-8"?><network-security-config> <domain-config> <domain includeSubdomains="true">example.com</domain> <trust-anchors> <certificates src="@raw/my_ca"/> </trust-anchors> </domain-config></network-security-config>
以 PEM 或 DER 格式將自簽署或非公共 CA 證書添加到 res/raw/my_ca
。這讓我回想起年前聽到滲透測試結果時的恐懼,好傢夥,自己裝了個證書...
這部分更多細節、功能請參考官方文檔網路安全配置
六、其他安全問題
1、日誌輸出
日誌是我們開發調試中不可或缺的一部分,但也是最容易泄露敏感信息的地方。所以,在我們發布應用時,應當關閉、甚至移除Log輸出。
2、混淆、加固
混淆代碼,可以增加反編譯破解的難度。但是我們在使用混淆功能時也要注意實體類、與JS交互的方法、第三方混淆配置等問題。
應用加固也是近年來比較熱門的應用安全解決方案,各大廠商都有自己的加固方案,常見的如騰訊樂固、360加固等等。
3、漏洞檢測工具
當項目代碼量龐大以後,積累了較多的歷史代碼,人工檢測代碼工作量大。這時,漏洞檢查工具就派上用場了。中文的漏洞檢測工具中比較有名的就是360的FireLine。
參考資料:
Security for Android Developers
Android Intent Scheme URLs攻擊
您的 Java 代碼安全嗎 — 還是暴露在外?
android WebView詳解,常見漏洞詳解和安全源碼
推薦閱讀: