1、权限过度声明风险
以下权限非需要不声明使用
CAMERA:访问相机
READ_EXTERNAL_STORAGE:读取SD卡上的内容
WRITE_EXTERNAL_STORAGE:修改/删除SD卡中的内容
RECORD_AUDIO:录音
READ_CONTACTS:读取联系人数据
2、加固壳、Java代码反编译风险、篡改和二次打包风险、so文件破解风险
前三者通过第三方免费或者付费进行,so加固暂未发现免费渠道
3、应用签名未校验风险
注意点:通过第三方加固后的签名sha1读取对比会返回fales,需要在第三方加固后重新签名,如果是第三方加固有选项记得勾上自动签名,故第三方加固提供签名校验的话自己不需要再写代码验证,验证反而会比对不一致。
4、代码未混淆风险
开启混淆
app下build.gradle的android->builTypes->release中 minfyEnabled true开启全局混淆
根据代码需求,决定混淆代码是分包混淆还是在app中一起混淆
混淆代码写在proguard-rules.pro中
基础混淆代码
#1.基本指令区
-optimizationpasses 5 #代码进行迭代优化的次数
-dontusemixedcaseclassnames #指定不同时产生混淆大小写混合的类名
-dontskipnonpubliclibraryclasses #指定不去忽略非公共的库的类
-dontskipnonpubliclibraryclassmembers #指定不去忽略非公共的库的类的成员
#-dontpreverify #android不需要
-verbose #生成映射文件
-ignorewarnings #除apk运行时产生的警告导致程序异常终止
-printmapping proguardMapping.txt #指定映射文件的名称
-optimizations !code/simplification/cast,!field/*,!class/merging/* #指定混淆时采用的算法,常用的谷歌推荐
-keepattributes *Annotation*,InnerClasses #保护代码中的Annotation不被混淆
-keepattributes Signature #避免混淆泛型
-keepattributes SourceFile,LineNumberTable #抛出异常时保留代码行号
#2.默认保留区
-keep public class * extends android.app.Activity
-keep public class * extends androidx.appcompat.app.AppCompatActivity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class * extends android.view.View
-keep class android.support.** {*;}
-keep public class * extends android.view.View{
*** get*();
void set*(***);
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * implements java.io
其他混淆注意事项
1、实体类代码不能混淆
-keep class com.example.test.JavaBean.** { *; }//.**为该文件夹下所有文件
-keep class com.example.test.TestBean { *; }//特指TestBean
2、第三方库混淆
引用第三方库的,记得加上第三方库提供的混淆内容
注意:Arouter除了它提供的混淆代码,@Route的path路径也是不能被混淆的,如果是用java类集中保存的路径,记得不要混淆
3、Parcalable序列化类不能被混淆
# 保留Parcelable序列化类不被混淆
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
4、部分回调函数不能被混淆
# 对于带有回调函数的onXXEvent、**On*Listener的,不能被混淆
-keepclassmembers class * {
void *(**On*Event);
void *(**On*Listener);
}
5、待补充。。。
5、使用WebView的各种风险
明文存储密码风险:
WebView.getSettings().setSavePassword(false) 关闭保存密码功能
Webview File同源策略绕过漏洞:
三个方案:
1、使用webview的activity组件设置不导出,即android:exported=false
2、需要导出,则禁止使用File域:WebView.getSettings.setAllowFileAccess(false)
3、需要File,则禁止调用JavaScript:WebView.getSettings.setJavaScriptEnabled(false)
未移除有风险的Webview系统隐藏接口漏洞:
在Webview加载前
webView.removeJavascriptInterface("searchBoxJavaBridge_");
webView.removeJavascriptInterface("accessibility");
webView.removeJavascriptInterface("accessibilityTraversal");
不安全的浏览器调用漏洞?:
不会搞。。。
6、密钥硬编码漏洞
专业密钥白盒,没钱
打包到so里,要加固so,没钱
给了一个动态生成密钥的方法,看了,没屁用,还是存在硬编码
7、动态调试攻击风险
不会
求助于第三方加固反动态调试,没钱
8、应用数据任意备份风险
AndroidManifest中,application标签里添加allowBackup=false,关闭数据备份功能
要么还是可以依赖于花了钱的第三方,贫穷啊
9、敏感函数调用风险?
有点生气,全是第三方库里调用的,不知道怎么搞,不懂免费加固之后还能不能检测到这个,焦急等待中
10、剪切板敏感信息泄露漏洞
android:longClickable=false
怎么说呢,除去登录修改密码啥的,我挺需要复制黏贴的,自己检查吧,敏感页面应当不允许
11、代码残留URL信息检测?
都是我使用的接口地址
大佬求带
先换了调用方法,通过传参在方法里返回完整的接口,新的报告还没出来,不知道管不管用,待更新
12、明文泄露风险
明明是用strings保存“用户名”,“密码”的字样的,根据资源名称含password、pwd、user等被误认为存了真实用户名密码密钥,哼你不智能不跟你计较
但确实,不要在资源文件中储存密码密钥等信息。我用工具破解了免费加固后的APK,资源文件的内容一览无余且百分比正确,不知道付费的能不能保护到位
有条件的,可以加固下资源文件
13、StrandHogg漏洞
给每个activity设置android:taskAffinity="" 设置为空
<!-- 12.12更新-->
- 使用taskAffinity=""遇到问题:每个activity都会出现在后台的最近任务中
解决方案:由于使用了singleTask,配合taskAffinity=""就会出现上述情况,也就是每个activity的task都不相同
使用setFlags(Intent.FALG_ACTIVITY_SINGLE_TOP|FALG_ACTIVITY_CLEAR_TOP)启动activity来代替launchMode="singleTask"
- 由于我使用了模块化开发,无法通过startActivity()设置Intent的FLAG来实现上述操作
方法一:通过暴露api的方法来实现startActivity
方法二:通过路由跳转(我使用的ARouter)
- ARouter的withFlags只能设置一个值,达不到效果,依旧存在上述问题
方法:使用ARouter时,navigation() 改为 navigation(context)
(PS:看了下源码,当navigation()时,最终的context会被赋值为ARouter初始化sARouter.init(application)中的application,如果调用了navigation(context)最终的context就会赋值为输入的context,而源码中,有这样一个判断,当context不是一个Activity时,intent的FLAG就会设置为singleTask模式,故同样导致了上述问题的存在)
14、访问境外服务器风险?
第三方库里,没辙,大佬求带
而且吧,也不都是访问,还有做字符串比较用的,虽然我不懂为什么要这样
15、界面劫持风险?
救救孩子吧
16、截屏攻击风险
针对敏感页面onCreate添加代码
getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE);//在setContentView前调用
17、动态注册Receiver风险
如果只需要应用内传递的广播:
1、通过LocalBroadcastManager实现动态注册,数据传递仅限应用内
2、也说可以静态注册BroadcastReceiver,并禁止导出exported=false(未实践)
或者,动态注册registerReceiver时,指定BroadcastReceiver接收时校验permission(未实践):
registerReceiver(BroadcastReceiver, IntentFilter, broadcastPermission,android.os.Handle)
18、Intent组件隐式调用风险?
都指向我intent发送广播的代码,是因为new Intent(action) 的action值都保存在java类里的缘故吗?还是我应该写intent.setAction(action) ?
19、反射调用风险?
这个,应该不重要吧。。。
20、模拟器运行风险、Root设备运行风险
第三方能搞,自己也可以搞,但我都加固了,感觉之前还检验模拟器和root有一点点多此一举
注意:
1、由于现在出了鸿蒙系统,检测硬件是否符合真机特征时,android.os.Build.BOOTLOADER值鸿蒙的和模拟器的一样,存在被误判
2、Android target 29开始,普通开发者无法获取手机的IMSI和IMEI值了,也就不能通过此判断真机和模拟器了
先这样吧,我提交上去测了