[TOC]
## 1 敏感信息检测 # 10001
通过正则表达式匹配敏感信息。
我们可以通过如下的几个正则表达式,匹配邮箱地址、手机号、电话号码、身份证号和QQ号等敏感的信息,看是否有在代码中出现,提醒开发者注意这些敏感信息,防止不必要的外泄。
邮箱地址
regexp5 = "[\w.-]+@[\w-]+\.[\w.]+"
手机号
regexp6 = "^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$"
电话号码
regexp7 = "\d{3}-\d{8}|\d{4}-\d{7}"
身份证号
regexp8 = "^\d{15}|\d{18}$"
QQ号
regexp9 = "[1-9][0-9]{4,}"
## 2 剪贴板敏感信息泄露风险检测 # 10002
由于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);
}
});
```
漏洞可以利用如下代码利用。
```
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ClipboardManager clipBoard = (ClipboardManager)getSystemService(CLIPBOARD_SERVICE);
clipBoard.addPrimaryClipChangedListener( new ClipboardListener() );
}
private void attack() {
ClipboardManager cm = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
ClipData cd2 = cm.getPrimaryClip();
String clipText = cd2.getItemAt(0).getText().toString();
//Log.v("clipboard", "Attacked: " + clipText);
Toast.makeText(getApplicationContext(), "Attacked: " + clipText, Toast.LENGTH_LONG).show();
}
class ClipboardListener implements ClipboardManager.OnPrimaryClipChangedListener {
public void onPrimaryClipChanged() {
attack();
}
}
}
```
建议:
避免使用剪贴板敏文存储敏感信息或进行加密。
## 3 Intent敏感数据泄露风险检测 # 10003
APP创建Intent传递数据到其他Activity,如果创建的Activity不是在同一个Task中打开,就很可能被其他的Activity劫持读取到Intent内容,跨Task的Activity通过Intent传递敏感信息是不安全的。
风险等级:`提醒`
问题示例:
检测是否使用了FLAG_ACTIVITY_NEW_TASK标志。
建议:
尽量避免使用包含FLAG_ACTIVITY_NEW_TASK标志的Intent来传递敏感信息。
## 4 PendingIntent误用风险 # 10004
使用pendingIntent时候,如果使用了一个空Intent,会导致恶意用户劫持Intent的内容。禁止使用空intent去构造pendingIntent。
风险等级:`中危`
问题示例:
通过判断代码片段中有没有出现以下函数,即可知道是否使用了空intent构造PendingIntent。
![PendingIntent误用风险-函数说明1](https://wiki-1252789527.cos.ap-shanghai.myqcloud.com/scan_model/image077.jpg)
![PendingIntent误用风险-函数说明2](https://wiki-1252789527.cos.ap-shanghai.myqcloud.com/scan_model/image079.jpg)
建议:
禁止使用空intent去构造pendingIntent。
## 5 密钥硬编码风险检测 # 10005
将密钥硬编码在Java代码、文件中,这样做会引起很大风险。**信息安全的基础在于密码学,而常用的密码学算法都是公开的,加密内容的保密依靠的是密钥的保密**,密钥如果泄露,对于对称密码算法,根据用到的密钥算法和加密后的密文,很容易得到加密前的明文;对于非对称密码算法或者签名算法,根据密钥和要加密的明文,很容易获得计算出签名值,从而伪造签名。
风险等级:`提醒`
检测使用以下加密算法的路径,目前该检测项只检测是否在Java层有**显式地**保存密钥,这应该是最有风险的一种保存方式。
```
AES/CBC/NoPadding
AES/CBC/PKCS7Padding
AES/CTR/NoPadding
AES/ECB/NoPadding
AES/ECB/PKCS7Padding
AES/GCM/NoPadding
RSA/ECB/NoPadding
RSA/ECB/PKCS1Padding
RSA/ECB/OAEPWithSHA-1AndMGF1Padding
RSA/ECB/OAEPWithSHA-224AndMGF1Padding
RSA/ECB/OAEPWithSHA-256AndMGF1Padding
RSA/ECB/OAEPWithSHA-384AndMGF1Padding
RSA/ECB/OAEPWithSHA-512AndMGF1Padding
RSA/ECB/OAEPPadding
```
## 6 数据或程序加载检查 # 10006
风险等级:`提醒`
需要进行动态分析
* 是否加载公共区域程序,如sdcard、/data/local/tmp/、应用自创建但其他应用有读写权限的目录上
* 是否从网络下载,检测方法包括:阅读代码、监听网路请求、见识存储区域文件读写、查看安装包
* 升级包是否存在公共区域存储
## 7 BASE64安全检测 # 10007
风险等级:`提醒`
检测出BASE64字符串,并解密。
## 8 文件全局读写漏洞检测 # 10008
在使用getDir、getSharedPreferences(SharedPreference)或openFileOutput时,如果设置了全局的可读权限,攻击者恶意读取文件内容,获取敏感信息。在设置文件属性时如果设置全局可写,攻击者可能会篡改、伪造内容,可能会进行诈骗等行为,造成用户财产损失。其中getSharedPreferences如果设置全局写权限,则当攻击app跟被攻击app具有相同的`Android:sharedUserId`属性时和签名时,攻击app则可以访问到内部存储文件进行写入操作。
风险等级:`中危`
问题示例:
检测出使用了getDir、getSharedPreferences和openFileOutput函数的参数值是否使用了`MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE`。
建议:
* 使用MODE_PRIVATE模式创建内部存储文件
* 加密存储敏感数据
* 避免在文件中存储明文敏感信息
* 避免滥用”Android:sharedUserId”属性
如果两个app`Android:sharedUserId`属性相同,切使用的签名也相同,则这两个app可以互相访问内部存储文件数据。
## 9 日志泄露风险检测 # 10009
在APP的开发过程中,为了方便调试,通常会使用log函数输出一些关键流程的信息,这些信息中通常会包含敏感内容,如执行流程、明文的用户名密码等,这会让攻击者更加容易的了解APP内部结构方便破解和攻击,甚至直接获取到有价值的敏感信息。
风险等级:`提醒`
问题示例:
检测是否调用了Log.v、Log.d、Log.e、Log.i、Log.w、Log.f、Log.s函数
建议:
在生产环境中移除Log打印。
## 10 外部加载Dex检测 # 10010
动态加载的DEX文件存储在被其他应用任意读写的目录中(如sdcard),如果没有对外部所加载的DEX文件做完整性校验,应用将会被恶意代码注入,从而执行的是恶意代码。
风险等级:`高危`
问题示例:
关键:public DexClassLoader (String dexPath, String optimizedDirectory, String libraryPath, ClassLoader parent)
首先获取所有调用了DexClassLoader函数的路径,然后对每个路径下的代码片段进行检查,判断有没有调用`Environment.getExternalStorageDirectory().toString()`该方法。两个条件同时满足,则判定该路径下的代码片段有风险。
建议:
* 将所需要动态加载的DEX/APK文件放置在APK内部或应用私有目录中
* 使用加密网络协议进行下载加载的DEX/APK文件并将其放置在应用私有目录中
* 对不可信的加载来源进行完整性校验
## 11 外部存储路径检测 # 10011
文件存放在external storage,例如SD卡,是全局可读写的。由于external storage可以被任何用户操作,且可以被所有的应用修改使用。所以,app的敏感数据建议不要存放在external storage。
风险等级:`低危`
动态方法监测`/data/data/<packagename>/`目录下所有生成的目录是否带有明文信息泄露
## 12 明文数字证书风险 # 10012
Apk中使用的数字证书可被用来校验服务器的合法身份,以及在与服务器进行通信的过程中对传输数据进行加密、解密运算,保证传输数据的保密性、完整性。明文存储的数字证书如果被篡改,客户端可能连接到假冒的服务端上,导致用户名、密码等信息被窃取;如果明文证书被盗取,可能造成传输数据被截获解密,用户信息泄露,或者伪造客户端向服务器发送请求,篡改服务器中的用户数据或造成服务器响应异常。
风险等级:`中危`
问题示例:
```
[
"assets/location_public_key.der",
"assets/verisign.cer",
"res/raw/servicecert.cer"
]
```