安卓開發開發規範手冊V1.0

安卓開發開發規範手冊V1.0

以前發佈過一份Web安全開發規範手冊V1.0,看到收藏文章的讀者挺多,發現整理這些文檔還挺有意義。html

最近週末抽了些時間把以前收集關於安卓安全開發的資料也整理了一下,整理出一份安卓安全開發手冊,大部份內容都是在一些博客看到各位師傅的分享。java

1、manifest文件安全

1.1 禁止PermissionGroup的屬性爲空

PermissionGroup能夠對permission進行一個邏輯上的分組。若是PermissionGroup的屬性爲空,會致使權限定義無效,且其餘app沒法使用該權限。android

開發建議

設置PermissionGroup屬性值或者不使用PermissionGroupweb

1.2 系統權限確認

App若是使用一些系統限制權限,諸如android.permission.WRITE_SECURE_SETTINGS和android.permission.INSTALL_PACKAGES,則該app應該是設備自帶的系統或google自帶的app,而且應該放置在/system/app目錄下。不然就是一個惡意app。算法

App使用下述權限,則該app有較高權限,要謹慎使用。sql

android.permission.MOUNT\_FORMAT\_FILESYSTEMS,

android.permission.MOUNT\_UNMOUNT\_FILESYSTEMS,

android.permission.RESTART\_PACKAGES。

開發建議

根據業務需求,如非必要,移除該權限。數據庫

1.3 protectionLevel屬性設置

因爲對app的自定義permission的protectionLevel屬性設置不當,會致使組件(如:content provider)數據泄露危險。最好的權限設置應爲signature或signatureOrSystem,進而避免被第三方應用利用。segmentfault

開發建議

注意使用signature或signatureOrSystem防止其餘app註冊或接受該app的消息,提升安全性。api

1.4 合理設置sharedUserId權限

經過sharedUserId,可讓擁有同一個User Id的多個apk運行在同一個進程中,互相訪問任意資源。將sharedUserId設置爲android.uid.system,能夠把app放到系統進程中,app將得到極大的權限。若是app同時有master key漏洞,容易致使被root。跨域

開發建議

合理設置軟件權限。

1.5 設置allowBackup爲false

當這個標誌被設置成true或不設置該標誌位時,應用程序數據能夠備份和恢復,adb調試備份容許惡意攻擊者複製應用程序數據。

開發建議

設置AndroidManifest.xml的android:allowBackup標誌爲false。

影響範圍

API >= 8

1.6 禁止Debuggable爲true

在AndroidManifest.xml中定義Debuggable項,若是該項被打開,app存在被惡意程序調試的風險,可能致使泄露敏感信息等問題。

開發建議

顯示的設置AndroidManifest.xml的debuggable標誌爲false。

2、組件安全

2.1 合理設置導出Activity、activity-alias、service、receiver

Activity、activity-alias、service、receiver組件對外暴露會致使數據泄露和惡意的dos攻擊。

開發建議

  1. 最小化組件暴露。對不會參與跨應用調用的組件添加android:exported=false屬性。
  2. 設置組件訪問權限。對跨應用間調用的組件或者公開的receiver、service、activity和activity-alias設置權限,同時將權限的protectionLevel設置爲signature或signatureOrSystem。
  3. 組件傳輸數據驗證。對組件之間,特別是跨應用的組件之間的數據傳入與返回作驗證和增長異常處理,防止惡意調試數據傳入,更要防止敏感數據返回。

2.2 Contentprovider信息泄露風險

provider組件導出可能會帶來信息泄露隱患。api level在17如下的全部應用的android:exported屬性默認值爲true,17及以上默認值爲false。

開發建議

  1. 最小化組件暴露。對不會參與跨應用調用的組件添加android:exported=false屬性。
  2. 設置組件訪問權限。對導出的provider組件設置權限,同時將權限的protectionLevel設置爲signature或signatureOrSystem。
  3. 因爲Contentprovider沒法在2(API-8)申明爲私有。故建議將min sdk設爲8以上。

影響範圍

api level在17如下的全部應用的android:exported屬性默認值爲true,17及以上默認值爲false。

2.3 嚴格過濾openFile對uri訪問

該漏洞因爲Content provider組件暴露,沒有對Content provider組件訪問權限進行限制且對Uri路徑沒有進行過濾,攻擊者經過Content provider實現的OpenFile接口進行攻擊,如經過../的方式訪問任意的目錄文件,形成隱私泄露。

開發建議

  1. 將沒必要要導出的Content provider設置爲不導出
  2. 因爲Android組件Content provider沒法在Android 2.2(即API Level 8)系統上設爲不導出,所以若是應用的Content provider沒必要要導出,阿里聚安全建議聲明最低SDK版本爲8以上版本;
  3. 因爲API level 在17如下的全部應用的android:exported屬性默認值都爲,所以若是應用的Content provider沒必要要導出,阿里聚安全建議顯示設置註冊的Content provider組件的android:exported屬性爲false;
  4. 去除沒有必要的penFile()接口
  5. 若是應用的Content provider組件沒有必要實現penFile()接口,阿里聚安全建議移除該Content provider的沒必要要的penFile()接口。
  6. 過濾限制跨域訪問,對訪問的目標文件的路徑進行有效判斷
  7. 使用decode()先對Content Query Uri進行解碼後,再過濾如可經過../實現任意可讀文件的訪問的Uri字符串;
  8. 設置權限來進行內部應用經過Content provider的數據共享
  9. 使用簽名驗證來控制Content provider共享數據的訪問權限,如設置protectionLevel=signature或signatureOrSystem;
  10. 公開的content provider確保不存儲敏感數據
  11. 提供asset文件時注意權限保護

2.4 使用顯式Intent 調用bindService()

建立隱式Intent 時,Android 系統經過將Intent 的內容與在設備上其餘應用的清單文件中聲明的Intent 過濾器進行比較,從而找到要啓動的相應組件。若是Intent 與Intent 過濾器匹配,則系統將啓動該組件,並將其傳遞給對象。若是多個Intent 過濾器兼容,則系統會顯示一個對話框,支持用戶選取要使用的應用。

爲了確保應用的安全性,啓動Service 時,請始終使用顯式Intent,且不要爲服務聲明Intent 過濾器。使用隱式Intent 啓動服務存在安全隱患,由於您沒法肯定哪些服務將響應Intent,且用戶沒法看到哪些服務已啓動。從Android 5.0(API 級別21)開始,若是使用隱式Intent 調用bindService(),系統會拋出異常。

開發建議

爲了確保應用的安全性,啓動 Service 時,請始終使用顯式 Intent,且不要爲服務聲明 Intent 過濾器。使用隱式 Intent 啓動服務存在安全隱患,由於您沒法肯定哪些服務將響應Intent,且用戶沒法看到哪些服務已啓動。從 Android 5.0(API 級別 21)開始,若是使用隱式 Intent 調用 bindService()),系統會拋出異常。

影響範圍

所有。從Android 5.0(API 級別21)開始,若是使用隱式Intent 調用bindService(),系統會拋出異常。

2.5 合理處理Intent Scheme URL

Intent Scheme URI是一種特殊的URL格式,用來經過Web頁面啓動已安裝應用的Activity組件,大多數主流瀏覽器都支持此功能。

Android Browser的攻擊手段——Intent Scheme URLs攻擊。這種攻擊方式利用了瀏覽器保護措施的不足,經過瀏覽器做爲橋樑間接實現Intend-Based攻擊。相比於普通Intend-Based攻擊,這種方式極具隱蔽性,

若是在app中,沒有檢查獲取到的load_url的值,攻擊者能夠構造釣魚網站,誘導用戶點擊加載,就能夠盜取用戶信息。因此,對Intent URI的處理不當時,就會致使基於Intent的攻擊。

若是瀏覽器支持Intent Scheme URI語法,通常會分三個步驟進行處理:

  1. 利用parseUri解析uri,獲取原始的intent對象;
  2. 對intent對象設置過濾規則;
  3. 經過startActivityIfNeeded或者startActivity發送intent;其中步驟2起關鍵做用,過濾規則缺失或者存在缺陷都會致使Intent Schem URL攻擊。

關鍵點

Intent.parseUri函數,經過掃描出全部調用了Intent.parseUri方法的路徑,並檢測是否使用以下的策略。

比較安全的使用Intent Scheme URI方法是:

若是使用了Intent.parseUri函數,獲取的intent必須嚴格過濾,intent至少包含addCategory(android.intent.category.BROWSABLE),setComponent(null),setSelector(null)3個策略。

因此,在檢的時候只要根據Intent.parseUri函數返回的Intent對象有沒有按照如下方式實現便可作出判斷:

// convert intent scheme URL to intent object

Intent intent = Intent.parseUri(uri);

 // forbid launching activities without BROWSABLE category

intent.addCategory(android.intent.category.BROWSABLE);

// forbid explicit call

intent.setComponent(null);

 // forbid intent with selector intent  intent.setSelector(null);

// start the activity by the intent

context.startActivityIfNeeded(intent, -1)

開發建議

若是使用了Intent.parseUri函數,獲取的intent必須嚴格過濾,intent至少包含addCategory(android.intent.category.BROWSABLE),setComponent(null),setSelector(null)3個策略。除了以上作法,最佳處理不要信任任何來自網頁端的任何intent,爲了安全起見,使用網頁傳過來的intent時,要進行過濾和檢查

2.6 本地拒絕服務

Android系統提供了Activity、Service和Broadcast Receiver等組件,並提供了Intent機制來協助應用間的交互與通信,Intent負責對應用中一次操做的動做、動做涉及數據、附加數據進行描述,Android系統則根據此Intent的描述,負責找到對應的組件,將Intent傳遞給調用的組件,並完成組件的調用。Android應用本地拒絕服務漏洞源於程序沒有對Intent.GetXXXExtra()獲取的異常或者畸形數據處理時沒有進行異常捕獲,從而致使攻擊者可經過向受害者應用發送此類空數據、異常或者畸形數據來達到使該應用Crash的目的,簡單的說就是攻擊者經過Intent發送空數據、異常或畸形數據給受害者應用,致使其崩潰。

對導出的組件傳遞一個不存在的序列化對象,若沒有try...catch捕獲異常就會崩潰

ComponentName cn = new ComponentName(com.test, com.test.TargetActivity)

Intent i = new Intent()

i.setComponentName(cn)

i.putExtra(key, new CustomSeriable())

startActivity(i)

**public class DataSchema implements Serializable {**

        public DataSchema() {

                super();

        }

}

2.6.1 NullPointerException 異常致使的拒絕服務

源於程序沒有對getAction()等獲取到的數據進行空指針判斷,從而致使了空指針異常致使應用崩潰

風險代碼:

Intent i = new Intent();

if (i.getAction().equals(TestForNullPointerException)) {

    Log.d(TAG, Test for Android Refuse Service Bug);

}

2.6.2 ClassCastException 異常致使的拒絕服務

源於程序沒有對getSerializableExtra()等獲取到的數據進行類型判斷而進行強制類型轉換,從而致使類型轉換異常致使拒絕服務漏洞

風險代碼:

Intent i = getIntent();

String test = (String) i.getSerializableExtra(serializable\_key);

**IndexOutOfBoundsException 異常致使拒絕服務漏洞**

源於程序沒有對getIntegerArrayListExtra()等獲取到的數據數組元素大小判斷,致使數組訪問越界而形成拒絕服務漏洞

風險代碼:

Intent intent = getIntent();

ArrayList<Integer> intArray = intent.getIntegerArrayListExtra(user\_id);

if (intArray != null) {

    for (int i = 0; i < 10; i++) {

        intArray.get(i);

    }

}

2.6.3 ClassNotFoundException 異常致使的拒絕服務漏洞

Intent i = getIntent();

getSerializableExtra(key);

開發建議

  1. 將比不要導出的組建設置爲不導出
  2. 在處理Intent數據時,進行捕獲異常,經過getXXXExtra()獲取的數據時進行如下判斷,以及用try catch方式捕獲全部異常,防止出現拒絕服務漏洞,包括:空指針異常、類型轉換異常、數組越界訪問異常、類未定義異常、其餘異常
Try{

    ....

xxx.getXXXExtra()

....

}Catch Exception{

**   **  **// 爲空便可**

}

2.7 合理定義android.intent.category.BROWSABLE

在AndroidManifest文件中定義了android.intent.category.BROWSABLE屬性的組件,能夠經過瀏覽器喚起,這會致使遠程命令執行漏洞攻擊

開發建議

  1. APP中任何接收外部輸入數據的地方都是潛在的攻擊點,過濾檢查來自網頁的參數
  2. 不要經過網頁傳輸敏感信息,有的網站爲了引導已經登陸的用戶到APP上使用,會使用腳本動態的生成URL Scheme的參數,其中包括了用戶名、密碼或者登陸態token等敏感信息,讓用戶打開APP直接就登陸了。惡意應用也能夠註冊相同的URL Sechme來截取這些敏感信息。Android系統會讓用戶選擇使用哪一個應用打開連接,可是若是用戶不注意,就會使用惡意應用打開,致使敏感信息泄露或者其餘風險。

2.8 刪除Debug和Test信息

一些app在正式發佈前,爲了方便調試app,都會在app裏集成一些調試或測試界面。這些測試界面可能包含敏感的信息。

開發建議

在正式發佈前移除全部的測試組件

2.9 Intent不安全反射風險

經過Intent接收的Extra參數來構造反射對象會致使從不受信任的源加載類。攻擊者能夠經過巧妙地構造達到加載其它類的目的

兩個關鍵函數,分別是:getIntent()和Class.forName(....)

public class SecondActivity extends Activity {

        @Override

            protected void onCreate(Bundle savedInstanceState) {

                super.onCreate(savedInstanceState);

                setContentView(R.layout.activity\_second);

                Intent intent = getIntent();

                String className = intent.getStringExtra(className);

                String methodName = intent.getStringExtra(methodName);

                try {

                        Class<?> clz = null;

                        clz = Class.forName(className);

                        Date object = (Date) clz.newInstance();

                        Method method = clz.getMethod(methodName);

                        Toast.makeText(getApplicationContext(), method.invoke(object, null) + ======, Toast.LENGTH\_LONG).show();

                } catch (Exception e) {

                        e.printStackTrace();

                }

        }

}

逆向後對應的smali代碼以下:

invoke-virtual {p0}, Lcom/bug/intent/reflection/SecondActivity;->getIntent()Landroid/content/Intent;

invoke-static {v0}, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;

開發建議

  1. 不要經過Intent接收的Extra傳播的反射函數
  2. 將接受反射的組件設置爲非導出組件

3、webview組件安全

3.1 WebView遠程執行漏洞

和WebView遠程代碼執行相關的漏洞主要有CVE-2012-6336,CVE-2014-1939,CVE-2014-7224, 這些漏洞中最核心的漏洞是CVE-2012-6336,另外兩個CVE只是發現了幾個默認存在的接口。

Android API < 17以前版本存在遠程代碼執行安全漏洞,該漏洞源於程序沒有正確限制使用addJavaScriptInterface(CVE-2012-6636)方法,攻擊者能夠經過Java反射利用該漏洞執行任意Java對象的方法,致使遠程代碼執行安全漏洞除。

開發建議

  1. API等於高於17的Android系統。出於安全考慮,爲了防止Java層的函數被隨意調用,Google在2版本以後,規定容許被調用的函數必須以@JavascriptInterface進行註解。
  2. API等於高於17的Android系統。建議不要使用addJavascriptInterface接口,以避免帶來沒必要要的安全隱患,若是必定要使用該接口:
  3. 若是使用https協議加載url,應用進行證書校驗防止訪問的頁面被篡改掛馬
  4. 若是使用http協議加載url,應進行白名單過濾、完整性校驗等防止訪問的頁面被篡改
  5. 若是加載本地html,應將html文件內置在apk中,以及進行對html頁面完整性的校驗
  6. 使用removeJavascriptInterface移除Android系統內部的默認內置接口:searchBoxJavaBridge_、accessibility、accessibilityTraversal

範圍:

CVE-2012-6636

Android API 16.0及以前的版本中存在安全漏洞,該漏洞源於程序沒有正確限制使用WebView.addJavascriptInterface方法。遠程攻擊者可經過使用Java Reflection API利用該漏洞執行任意Java對象的方法

Google Android <= 4.1.2 (API level 16) 受到此漏洞的影響。

CVE-2014-1939

java/android/webkit/BrowserFrame.java

使用addJavascriptInterface API並建立了SearchBoxImpl類的對象。攻擊者可經過訪問searchBoxJavaBridge_接口利用該漏洞執行任意Java代碼。

Google Android <= 4.3.1 受到此漏洞的影響

CVE-2014-7224

香港理工大學的研究人員發現當系統輔助功能中的任意一項服務被開啓後,全部由系統提供的WebView都會被加入兩個JS objects,分別爲是accessibility和accessibilityTraversal。惡意攻擊者就可使用accessibility和accessibilityTraversal這兩個Java Bridge來執行遠程攻擊代碼.

Google Android < 4.4 受到此漏洞的影響。

3.2 WebView潛在XSS攻擊

容許WebView執行JavaScript(setJavaScriptEnabled),有可能致使XSS攻擊。

開發建議

應儘可能避免使用。若是必定要使用:

  1. API等於高高於17的Android系統。出於安全考慮,爲了防止Java層的函數被隨意調用,Google在2版本以後,規定容許被調用的函數必須以@JavascriptInterface進行註解。
  2. API等於高高於17的Android系統。建議不要使用addJavascriptInterface接口,一面帶來沒必要要的安全隱患,若是必定要使用該接口:
  3. 若是使用https協議加載url,應用進行證書校驗防止訪問的頁面被篡改掛馬
  4. 若是使用http協議加載url,應進行白名單過濾、完整性校驗等防止訪問的頁面被篡改
  5. 若是加載本地html,應將html文件內置在apk中,以及進行對html頁面完整性的校驗
  6. 使用removeJavascriptInterface移除Android系統內部的默認內置接口:searchBoxJavaBridge_、accessibility、accessibilityTraversal

影響範圍

Android api <17

3.3 WebView File域同源策略繞過

應用程序一旦使用WebView並支持File域,就會受到該漏洞的攻擊。該漏洞源於:JavaScript的延時執行可以繞過file協議的同源檢查,並可以訪問受害應用的全部私有文件,即經過WebView對Javascript的延時執行和將當前Html文件刪除掉並軟鏈接指向其餘文件就能夠讀取到被符號連接所指的文件,而後經過JavaScript再次讀取HTML文件,便可獲取到被符號連接所指的文件。

大多數使用WebView的應用都會受到該漏洞的影響,惡意應用經過該漏洞,可在無特殊權限下盜取應用的任意私有文件,尤爲是瀏覽器,可經過利用該漏洞,獲取到瀏覽器所保存的密碼、Cookie、收藏夾以及歷史記錄等敏感信息,從而形成敏感信息泄露。

開發建議

  1. 將沒必要要導出的組件設置爲不導出

    若是應用的組件沒必要要導出,建議顯式設置所註冊組件的android:exported屬性爲false;

  2. 若是須要導出組件,禁止使用File域

    若是應用的須要導出包含WebView的組件,建議禁止使用File域協議:

myWebView.getSettings. setAllowFileAccess(false);

  1. 若是須要使用File協議,禁止File協議調用JavaScript

    若是應用的WebView須要使用File域協議,建議禁止File域協議調用JavaScript:

myWebView.getSettings. setJavaScriptEnabled(false);

3.4 禁止webview密碼明文存儲

webview的保存密碼功能默認設置爲true。Webview會明文保存網站上的密碼到本地私有文件databases/webview.db中。對於能夠被root的系統環境或者配合其餘漏洞(如webview的同源繞過漏洞),攻擊者能夠獲取到用戶密碼。

image

開發建議

顯示設置webView.getSetting().setSavePassword(false)

3.5 主機名弱校驗漏洞

自定義HostnameVerifier類,卻不實現verify方法驗證域名,致使中間人攻擊漏洞。

開發建議

自定義HostnameVerifier類並實現verify方法驗證域名。

3.6 證書弱校驗漏洞

App在實現X509TrustManager時,默認覆蓋google默認的證書檢查機制方法:checkClientTrusted、checkServerTrusted和getAcceptedIssuers,會致使中間人攻擊漏洞。

開發建議

若是本身建立X509Certificate,則在覆蓋checkClientTrusted、checkServerTrusted和getAcceptedIssuers後要進行校驗。

3.7 中間人攻擊漏洞

App調用setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER),信任全部主機名,會致使中間人攻擊。

開發建議

查找全部設置了ALLOW_ALL_HOSTNAME_VERIFIER字段屬性的方法路徑;對信任的主機嚴格認證

3.8 WebView不校驗證書漏洞

Android WebView組件加載網頁發生證書認證錯誤時,會調用WebViewClient類的onReceivedSslError方法,若是該方法實現調用了handler.proceed()來忽略該證書錯誤,則會受到中間人攻擊的威脅,可能致使隱私泄露。

自定義實現的WebViewClient類在onReceivedSslError是否調用proceed()方法。

開發建議

當發生證書認證錯誤時,採用默認的處理方法handler.cancel(),中止加載問題頁面當發生證書認證錯誤時,採用默認的處理方法handler.cancel(),中止加載問題頁面

3.9 WebView組件系統隱藏接口未移除

android webview組件包含3個隱藏的系統接口:searchBoxJavaBridge_,accessibilityTraversal以及accessibility,惡意程序能夠利用它們實現遠程代碼執行。

風險代碼:

const-string v3, searchBoxJavaBridge\_

invoke-virtual {v1, v3}, Landroid/webkit/WebView;->removeJavascriptInterface(Ljava/lang/String;)V

const-string v3, accessibility

invoke-virtual {v1, v3}, Landroid/webkit/WebView;->removeJavascriptInterface(Ljava/lang/String;)V

const-string v3, accessibilityTraversal

invoke-virtual {v1, v3}, Landroid/webkit/WebView;->removeJavascriptInterface(Ljava/lang/String;)V

開發建議

使用了WebView,那麼使用WebView.removeJavascriptInterface(String name) API,顯示的移除searchBoxJavaBridge_、accessibility、accessibilityTraversal這三個接口

影響範圍

4.0~4.4(不包含)

4、sqlite安全

4.1 SQLite sql注入漏洞

SQLite作爲android平臺的數據庫,對於數據庫查詢,若是開發者採用字符串連接方式構造sql語句,就會產生sql注入。

開發建議

  1. provider不須要導出,請將export屬性設置爲false
  2. 若導出僅爲內部通訊使用,則設置protectionLevel=signature
  3. 不直接使用傳入的查詢語句用於projection和selection,使用由query綁定的參數selectionArgs
  4. 完備的SQL注入語句檢測邏輯

4.2 Databases任意讀寫漏洞

APP在使用openOrCreateDatabase建立數據庫時,將數據庫設置了全局的可讀權限,攻擊者惡意讀取數據庫內容,獲取敏感信息。在設置數據庫屬性時若是設置全局可寫,攻擊者可能會篡改、僞造內容,能夠能會進行詐騙等行爲,形成用戶財產損失。

開發建議

  1. 用MODE_PRIVATE模式建立數據庫
  2. 使用sqlcipher等工具加密數據庫
  3. 避免在數據庫中存儲明文和敏感信息

網絡通訊安全

5.1 SSL不安全組件

SSLCertificateSocketFactory#getInsecure方法沒法執行SSL驗證檢查,使得網絡通訊遭受中間人攻擊。

開發建議

移除SSLCertificateSocketFactory#getInsecure方法。

5.2 HttpHost安全

HttpHost target = new HttpHost(uri.getHost(), uri.getPort(), HttpHost.DEFAULT_SCHEME_NAME);

HttpHost.DEFAULT_SCHEME_NAME默認是http,不安全。

開發建議

改爲使用https

5.3 HttpURLConnection漏洞

在Android 2.2版本以前,HttpURLConnection一直存在着一些使人厭煩的bug。好比說對一個可讀的InputStream調用close()方法時,就有可能會致使鏈接池失效了。

開發建議

判斷Android版本,並設置http.keepAlive爲false。

private void disableConnectionReuseIfNecessary() {

        // Work around pre-Froyo bugs in HTTP connection reuse.

        if (Integer.parseInt(Build.VERSION.SDK) < Build.VERSION\_CODES.FROYO) {

                System.setProperty(http.keepAlive, false);

        }

}

影響範圍

2.2版本以前

6、弱加密風險檢測

6.1 禁止使用弱加密算法

安全性要求高的應用程序必須避免使用不安全的或者強度弱的加密算法,現代計算機的計算能力使得攻擊者經過暴力破解能夠攻破強度弱的算法。例如,數據加密標準算法DES(密鑰默認是56位長度、算法半公開、迭代次數少)是極度不安全的,使用相似EFF(Electronic Frontier Foundaton)Deep Crack的計算機在一天內能夠暴力破解由DES加密的消息。

使用DES弱加密算法,樣例

風險代碼:

SecretKeySpec key = new SecretKeySpec(rawKeyData, DES);

Cipher cipher = Cipher.getInstance(DES/ECB/PKCS5Padding);

cipher.init(Cipher.DECRYPT\_MODE, key);

開發建議

建議使用安全性更高的AES加密算法

規範 6.2 不安全的密鑰長度風險

在使用RSA加密時,密鑰長度小於512bit,小於512bit的密鑰很容易被破解,計算出密鑰。

風險代碼:

public static KeyPair getRSAKey() throws NoSuchAlgorithmException {

        KeyPairGenerator keyGen = KeyPairGenerator.getInstance(RSA);

        keyGen.initialize(512);

        KeyPair key = keyGen.generateKeyPair();

        return key;

      }

開發建議

使用RSA加密時,建議密鑰長度大於1024bit

6.3 AES/DES弱加密風險(ECB)

AES的ECB加密模式容易遭到字典攻擊,安全性不夠。

風險代碼:

SecretKeySpec key = new SecretKeySpec(keyBytes, AES);

**Cipher cipher = Cipher.getInstance(AES/ECB/PKCS7Padding, BC);**

cipher.init(Cipher.ENCRYPT\_MODE, key);

開發建議

避免使用ECB模式,建議使用CBC。

6.4 IVParameterSpec不安全初始化向量

使用IVParameterSpec函數,若是使用了固定的初始化向量,那麼密碼文本可預測性高得多,容易受到字典攻擊等。

風險代碼:

byte[] iv = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };

IvParameterSpec ips = new IvParameterSpec(iv)

開發建議

IVParameterSpec初始化時,不使用常量vector。

6.5 RSA中不使用Padding風險

使用RSA公鑰時一般會綁定一個padding,緣由是爲了防止一些依賴於no padding時對RSA算法的攻擊。

風險代碼:

Cipher rsa = null;

try {

  rsa = javax.crypto.Cipher.getInstance(RSA/NONE/NoPadding);

}catch (java.security.NoSuchAlgorithmException e) {}

catch (javax.crypto.NoSuchPaddingException e) {}

SecretKeySpec key = new SecretKeySpec(rawKeyData, RSA);

Cipher cipher = Cipher.getInstance(RSA/NONE/NoPadding);

cipher.init(Cipher.DECRYPT\_MODE, key);

開發建議

建議使用Padding模式。

6.6 KeyStore弱密碼風險

keytool是一個Java數據證書的管理工具,Keytool將密鑰(key,私鑰和公鑰配對)和證書(certificates)存在一個稱爲keystore的文件中,並經過密碼保護keystore中的密鑰。若是密碼設置過於簡單,例如:12345六、android等,則會致使keystore文件的私鑰泄露,從而致使一系列的信息泄露風險。

開發建議

提升keystore保護密碼的強度

7、數據安全

7.1 剪貼板敏感信息泄露風險

因爲Android剪貼板的內容向任何權限的app開放,很容易就被嗅探泄密。同一部手機中安裝的其餘app,甚至是一些權限不高的app,均可以經過剪貼板功能獲取剪貼板中的敏感信息。

風險代碼:

clipBtn = (Button) findViewById(R.id.btn\_clip);

        clipBtn.setOnClickListener(new OnClickListener() {

            @Override

            public void onClick(View v) {

                ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD\_SERVICE);

                ClipData clip1 = ClipData.newPlainText(label,password=123456);

                clipboard.setPrimaryClip(clip1);

            }

        });

開發建議

避免使用剪貼板敏文存儲敏感信息或進行加密

7.2 密鑰硬編碼風險

在代碼中禁止硬編碼私鑰等敏感信息,攻擊者反編譯代碼,便可拿到。

7.3 Intent敏感數據泄露

APP建立Intent傳遞數據到其餘Activity,若是建立的Activity不是在同一個Task中打開,就極可能被其餘的Activity劫持讀取到Intent內容,跨Task的Activity經過Intent傳遞敏感信息是不安全的。

開發建議

儘可能避免使用包含FLAG_ACTIVITY_NEW_TASK標誌的Intent來傳遞敏感信息。

7.4 PendingIntent誤用風險

使用pendingIntent時候,若是使用了一個空Intent,會致使惡意用戶劫持Intent的內容。禁止使用空intent去構造pendingIntent。

開發建議

禁止使用空intent去構造pendingIntent。

7.5 數據或程序(DEX、SO)加載、刪除檢查

程序在加載外部dex、so文件是否判斷文件來源、是否存放可信區域;程序刪除文件是否可篡改文件路勁

  1. 是否加載公共區域程序,如sdcard、/data/local/tmp/、應用自建立但其餘應用有讀寫權限的目錄上
  2. 是否從網絡下載,檢測方法包括:閱讀代碼、監聽網路請求、見識存儲區域文件讀寫、查看安裝包
  3. 升級包是否存在公共區域存儲。

7.6 文件全局讀寫漏洞

在使用getDir、getSharedPreferences(SharedPreference)或openFileOutput時,若是設置了全局的可讀權限,攻擊者惡意讀取文件內容,獲取敏感信息。在設置文件屬性時若是設置全局可寫,攻擊者可能會篡改、僞造內容,可能會進行詐騙等行爲,形成用戶財產損失。其中getSharedPreferences若是設置全局寫權限,則當攻擊app跟被攻擊app具備相同的Android:sharedUserId屬性時和簽名時,攻擊app則能夠訪問到內部存儲文件進行寫入操做。

開發建議

  1. 使用MODE_PRIVATE模式建立內部存儲文件
  2. 加密存儲敏感數據
  3. 避免在文件中存儲明文敏感信息
  4. 避免濫用Android:sharedUserId屬性

若是兩個appAndroid:sharedUserId屬性相同,切使用的簽名也相同,則這兩個app能夠互相訪問內部存儲文件數據

7.7 日誌泄露風險

在APP的開發過程當中,爲了方便調試,一般會使用log函數輸出一些關鍵流程的信息,這些信息中一般會包含敏感內容,如執行流程、明文的用戶名密碼等,這會讓攻擊者更加容易的瞭解APP內部結構方便破解和攻擊,甚至直接獲取到有價值的敏感信息。

開發建議

禁止打印敏感信息

8、其餘風險

8.1 謹慎使用高風險函數

在程序須要執行系統命令等函數,須要謹慎使用,嚴格控制命令來源,防止黑客替換命令攻擊。

風險代碼:

Example Java code:

  Runtime rr = Runtime.getRuntime();

  Process p = rr.exec(ls -al);

Example Bytecode code:

  const-string v2, ls -al

  invoke-virtual {v1, v2}, Ljava/lang/Runtime;->exec(Ljava/lang/String;)Ljava/lang/Process;

開發建議

嚴格按照要求使用

8.2 Fragment注入漏洞(CVE-2013-6271)

在api level 小於19的app,全部繼承了PreferenceActivity類的activity並將該類置爲exported的應用都受到Fragment注入漏洞的威脅。

Google在Android 4.4 KitKat 裏面修正了該問題,引入了PreferenceActivity.isValidFragment函數,要求用戶重寫該函數驗證Fragment來源正確性。

開發建議

  1. 當Android api >=19時,要覆蓋每個PreferenceActivity類下的isValidFragment方法以免異常拋出;
  2. 當Android api < 19時,若是在PreferenceActivity內沒有引用任何fragment,建議覆蓋isValidFragment並返回false

影響範圍

小於Android 4.4(API level 19)

8.3 SQLite數據庫日誌泄露漏洞(CVE-2011-3901)

Android SQLite數據庫journal文件可被全部應用程序讀取,全部目錄對應程序數據庫目錄擁有執行權限,意味着應用程序數據目錄全局訪問,/data/data/<app package>/databases目錄以[rwxrwx--x]權限建立,可致使全局讀寫。數據庫目錄下建立的journal文件以[-rw-r--r--]權限建立,可被全部app讀取。

開發建議

升級到Android4.0.1以上版本或者使用SQLCipher或其餘庫加密數據庫和日誌信息。

影響範圍

Android2.3.7版本存在該漏洞,其餘版本可能也受到影響,4.0.1不受影響

8.4 隨機數生成漏洞

SecureRandom的使用不當會致使生成的隨機數可被預測,該漏洞存在於Android系統隨機生成數字串安全密鑰的環節中。該漏洞的生成緣由是對SecureRandom類的不正確使用方式致使生成的隨機數不隨機。

風險代碼:

SecureRandom secureRandom = new SecureRandom();

        byte[] b = new byte[] { (byte) 1 };

        secureRandom.setSeed(b);

        // Prior to Android 4.2, the next line would always return the same number!

        Log.v(wgc,-------------------------------);

        Log.v(wgc,Test1: + secureRandom.nextInt());

        SecureRandom secureRandom2 = new SecureRandom(new byte[] { (byte) 1 });

        Log.v(wgc,Test2: + secureRandom2.nextInt());

        SecureRandom secureRandom3 = new SecureRandom();

        secureRandom3.setSeed(10L);

        Log.v(wgc,Test3: + secureRandom3.nextInt())

        SecureRandom secureRandom4 = new SecureRandom();

        secureRandom4.nextBytes(b);

        secureRandom4.setSeed(10L);

        Log.v(wgc,Test4: + secureRandom4.nextInt());

        SecureRandom secureRandom5 = new SecureRandom();

        Log.v(wgc,Test5: + secureRandom4.nextInt());

開發建議

  1. 不要使用自定義隨機源代替系統默認隨機源(推薦)除非有特殊需求,在使用SecureRandom類時,不要調用如下函數:SecureRandom類下SecureRandom(byte[]seed)、setSeed(long seed)和setSeed(byte[]seed)方法。
  2. 在調用setSeed方法前先調用任意nextXXX方法。具體作法是調用setSeed方法前先調用一次SecureRandom#nextBytes(byte[]bytes)方法,能夠避免默認隨機源被替代,詳細見參考資料。

影響範圍

Android 4.2以前,Android API 17之後SecureRandom的默認實現方式從Cipher.RSA換到了OpenSSL。SecureRandom新的實現方式不能將本身的seed替換掉系統的seed。

8.5 發佈版本需加固

發佈的軟件,應對app進行加固,防止攻擊者獲取app代碼、業務邏輯、API接口等,對業務和公司聲譽形成必定影響,防止app被破解二次打包,致使損失。

開發建議 APP加固


內容編輯:湯青松

更新時間:2019-09-03

相關文章
相關標籤/搜索