Android 隱私合規檢測

語言: CN / TW / HK

目前應用市場的隱私合規檢查越來越嚴格,各大手機廠商的檢測標準也不一致,經常有這個平台過審了那個平台還有問題出現,按照工信部的要求,工信部隱私合規説明。隱私合規是個不可不重視的點。

我們通常遇到的主要問題:
  • 在用户同意隱私協議之前,不能有收集用户隱私數據的行為。例如:在用户同意協議之前不能去獲取 Android ID、Device ID、MAC 等隱私數據。

  • 在用户同意隱私協議之後,獲取權限時必須要符合當前使用場景,例如:我們需要獲取手機讀寫,相機權限,這種需要在真正的讀寫,打開相機等頁面時才能去請求權限。

如上問題處理可分為兩種:權限 和 隱私
  • 權限 需要在對應頁面即 app內獲取權限時主動設置彈窗等方式給予app相應的權限

    '如電話權限,定位權限,相機權限,浮窗權限,讀寫權限等。在每個申請危險權限前,都需要彈窗説明權限解釋説明。' - 隱私 為app使用過程中與用户個人相關的個人信息

    '如位置,Mac地址,設備id等。就Android端而言,多數隱私信息需要對應授權後才能獲取,但目前仍存在部分隱私信息無需授權就可以拿到的'

如何檢測

一、第三方檢測

京數安掃描平台國舜網易雲盾

二、靜態檢測
  • Lint 檢查項目

    Lint用於檢測靜態代碼和資源,找到其中不符合預定義規則的地方。可參考網易雲隱私合規靜態檢查

  • 反編譯查找對應方法

    反編譯主要是為了找出第三方的一些不合規方法調用,但是比較麻煩,全局搜索很不方便

三、動態檢測(開源)
  • 1、Xposed

    優點 :Xposed 是比較早的做hook的框架, Xposed框架可以在不修改APK文件的情況下影響程序運行(修改系統)的框架服務,基於它可以製作出許多功能強大的模塊,且在功能不衝突的情況下同時運作。Android中一般存在兩種hook:sdk hook和ndk hook。native hook的難點在於理解ELF文件與學習ELF文件,Java層Hook則需要了解虛擬機的特性與java上的反射使用。另外還存在全局hook,即結合sdk hook和ndk hook,xposed就是一種典型的全局hook框架。

    缺點:需要手機ROOT

  • 2、VirtualXposed

    優點 :VirtualXposed 是基於VirtualApp 和 epic 實現的,能在非ROOT環境下直接運行Xposed模塊 (目前支持5.0~10.0)。其實VirtualXposed就是一個支持Xposed的虛擬機,我們把開發好的Xposed模塊和對應需要hook的App安裝上去就能實現hook功能。

    缺點:步驟相對麻煩,de.robv.android.xposed 的依賴需要翻牆。

  • 3、epic

    優點 :配置簡單,屬於運行時hook,説明在動態加載dex也能檢測到,也是我目前再用的,可以自定義配置hook 對應的類和方法,並找出當前調用線程堆棧,直接定位到調用的方法。

    缺點:兼容問題,Android 11及以上只能支持 64位,不過這個不影響11以下的使用;只檢測java類代碼,native沒有hook 。

  • 4、PrivacySentry

    接入相對複雜,基於自定義transform , 編譯期註解+hook方案,第一個transform收集需要攔截的敏感函數,第二個transform替換敏感函數,運行期收集日誌,同時支持遊客模式。

    有java.util.zip.ZipException: duplicate entry: META-INF/INDEX.LIST 衝突風險。

  • 5、camille

    使用 python Frida 等工具命令,做hook 模塊,手機需要Root,功能強大但相對複雜

  • 6、自定義Asm插件,做代碼插入檢測

    可以在class->dex時,對相應的類、調用方法,做檢測。添加我們的攔截代碼

四、epic落地
  • 我這裏使用的時 epic 檢測,直接依賴:

implementation 'me.weishu:epic:1.0.0' implementation 'me.weishu.exposed:exposed-xposedapi:0.4.5'

主要核心是 DexposedBridge.findAndHookMethod 方法

``` //targetClass: 傳入 需要hook 的類,如:TelephonyManager.class //targetMethod:類對應的方法,如:getDeviceId DexposedBridge.findAndHookMethod(targetClass, targetMethod, new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { super.beforeHookedMethod(param);

    //被調用的類名
    String className = param.method.getDeclaringClass().getName();
    //被調用的函數名
    String methodName = param.method.getName();
    LogAction.log("檢測到 " + className + " 被調用: methodName=" + methodName);
    //這裏可以蒐集當前的線程信息,堆棧等,將調用關係打印出來,例如:

    //Thread thread = Thread.currentThread();
    //StringBuilder stringBuilder = new StringBuilder();
    //獲取線程信息
    //String threadInfo = getThreadInfo(thread);
    //stringBuilder.append(threadInfo);
    // 返回表示此線程的堆棧轉儲的堆棧跟蹤元素數組。
   // 如果這個線程還沒有啟動,已經啟動但還沒有被系統計劃運行,或者已經終止,這個方法將返回一個零長度的  數組。
    //StackTraceElement[] stackTraceElements = thread.getStackTrace();
    //String print = printToString2(stackTraceElements);
    //stringBuilder.append("線程堆棧日誌:").append(print);

    //LogAction.log(stringBuilder);
}

@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
    super.afterHookedMethod(param);

}

}); ```

例如,我這裏用了 leakcanary 做檢測時會提示的

image.png

因為我對 android.app.ApplicationPackageManager 這個類做了檢測,queryIntentActivities 方法被調用時即觸發了beforeHookedMethod

五、集成優化處理
  • 我們可以自己定義一個module模塊,單獨處理合規檢測,利用 debugImplementation 的方式集成,不會影響到線上
  • 可以使用 ContentProvider 做初始化入口,debugImplementation 集成進來即可,在 ContentProvider onCreate 的時候去 start啟用 需要hook 的集合類。
  • 可以使用企業微信提供 API  Token,在收到 隱私限制方法被調用時,觸發消息發送,方便測試和提示,不需要去看log日誌。