用例风险:源代码未做混淆使攻击者很轻易反编译出源代码导致代码泄漏风险。
执行步骤:使用反编译工具打开应用,如发现代码内未经过混淆,就说明存在应用可进行反编译,记录漏洞,停止测试。
预期结果:安装包中核心模块与敏感数据经过加密或者混淆
整改建议:建议使用Proguard
等工具对源码进行进一步混淆,避免造成源码泄漏。
用例风险: Android
签名机制是一种有效的身份标识,为了保证应用不被恶意修改后重新发布,需要检查应用签名是否有保护机制。
执行步骤
.apk
文件后,删除META-INF/
目录下的xx.RSA
和xxx.SF
文件apk
文件进行重新签名,首先生成自己的私钥`keytool -genkey -v -keystore [keystore路径] -alias [密钥别名] -keyalg RSA -keysize 2048 -validity [有效天数]`
apk
进行二次签名,签名命令格式如下jarsigner -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore [keystore名称] [apk文件] [密钥别名]
-sigalg
:签名算法名称-digestalg
:信息摘要算法-keystore
:签名文件执行签名命令
jarsigner -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore android.keystore kaoyan.apk android.keystore
预期结果: 更换签名后,触发应用防御机制,应用无法启动或提示
整改建议: 内部代码实现apk
二次打包鉴别机制,在程序运行时校验apk
签名是否由官方私钥签名而来。
用例风险:应用权限分配不合理,可能导致用户隐私数据泄露。
执行步骤
AndoridManifest.xml
文件,将应用权限和业务功能需要权限做对比,检查申请应用权限是否大于业务需要权限,有即存在安全隐患。预期结果:应用申请合理的系统权限
整改建议:为应用分配合理的系统权限
用例风险:当allowBackup
标志值为true
时,即可通过adb backup
和adb restore
来备份和恢复应用程序数据,导致应用数据泄露。
执行步骤
AndroidManifest.xml
文件;AndoridManifest.xml
文件中的配置是否为:android:allowBackup="true"
,即为allowBackup
开启,记录漏洞,停止测试。预期结果:AllowBackup
关闭
整改建议:在AndroidManifest.xml
文件设置allowBackup
属性值为False
。
备注:allowBackup
属性未配置时默认为true
用例风险:当debuggable
标志值为true
时,即表示是App
可调试的,存在安全泄露风险。
执行步骤
AndroidManifest.xml
文件;AndoridManifest.xml
文件中的配置是否为:android: debuggable="true"
,即为debuggable
开启。预期结果 debuggable
关闭
整改建议 在AndroidManifest.xml
文件设置debuggable
属性值,其默认值为false
备注 Debuggable
属性未配置时默认为false
用例风险
使用弱加密算法会大大增加黑客攻击的概率,黑客可能会破解隐私数据、猜解密钥、中间人攻击等,造成隐私信息的泄漏,甚至造成财产损失。容易被破解的加密算法被称为弱加密算法,例如可以使用穷举法在有限的时间内破解DES
算法。
执行步骤
DES
弱加密算法,弱加密代码样例:SecretKeySpec key = new SecretKeySpec(rawKeyData, "DES"); //指定加密方式
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); //设置加密填充模式
cipher.init(Cipher.DECRYPT_MODE, key);
RSA中
加密不使用Padding
:RSA
加密常用的填充模式有三种:RSA_PKCS1_PADDING
RSA_PKCS1_OAEP_PADDING
RSA_NO_PADDING
使用RSA
公钥时通常会绑定一个Padding
,原因是为了防止对RSA
算法的攻击。风险代码样例如下:扩展资料: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"); //选择了NoPadding加密模式
cipher.init(Cipher.DECRYPT_MODE, key);
512bits
常用的密钥长度有
1024bits
,2048bits
等,使用RSA
加密时,建议密钥长度大于1024bit
public static KeyPair getRSAKey() throws NoSuchAlgorithmException {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(512); //密码长度设置为512bits
KeyPair key = keyGen.generateKeyPair();
return key;
}
AES
加密使用了ECB模式
。
ECB
模式是最简单的模式,在其中明文和密文是一一对应的,相同的明文会被加密为相同的密文,这样可以通过观察密文得到明文中重复的组合,并以此为线索来破解密码。
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, key);
预期结果:系统未使用包含风险的加密算法
整改建议
DES
算法RSA
算法加密时不使用NoPadding
ECB
模式RSA
加密时,建议密钥长度大于1024bit
用例风险:如果在传输过程中未对敏感数据进行加密传输,存在被恶意攻击者通过网络窃听等手段获取网络数据包中的敏感数据的威胁。
执行步骤
Charles
),查看数据包中是否明文包含:用户名密码、IP
地址、SIM
序列号,或其他用户、系统等敏感信息。预期结果:传输的数据包中未包含敏感信息
整改建议:确保包含重要敏感信息的数据均已加密的形式或者以https
形式传输。
用例风险
在密码学和计算机安全领域中,中间人攻击(Man-in-the-middle attack
,缩写:MITM
)是指攻击者与通讯的两端分别建立独立的联系,并交换其所收到的数据,使通讯的两端认为他们正在通过一个私密的连接与对方直接对话,但事实上整个会话都被攻击者完全控制。在中间人攻击中,攻击者可以拦截通讯双方的通话并插入新的内容。
执行步骤
public class SSLSocketFactory_poc extends SSLSocketFactory {
SSLContext sslContext = SSLContext.getInstance("TLS");
public SSLSocketFactory_poc(KeyManager[] keys,KeyStore truststore ) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
super(truststore);
TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) {
if(true)
{}
try {
throw new CertificateException("illegal DN, reject the connection");
} catch (CertificateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sslContext.init(keys, new TrustManager[] { tm }, null);
}
...
}s(), "js2java");
HostnameVerifier hostnameVerifier = new HostnameVerifier(){
public boolean verify(String hostname, SSLSession session)
{
return true; #未实现任何判断语句,直接返回true
};
};
SSLSocketFactory sf = new SSLSocketFactory_poc(null,trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); #允许所有域名
sf.setHostnameVerifier(new AllowAllHostnameVerifier());
预期结果:在使用证书的时候进行相关校验
整改建议:建议开发者对SSL
证书进行强校验,包括证书是否合法、主机域名是否合法和证书的有效期。
安全风险
如果日志中包含用户信息、业务信息,攻击者可以通过抓取日志,搜集整理大量的有用信息。比如有时研发开发时为了调试方便会添加一些debug
日志,如果在打正式发布包时不将这些log
去掉那么很容易泄漏敏感信息。
执行步骤
adb logcat | find "com.youku.phone"(包名)"
捕获输出的日志adb logcat | find "com.youku.phone" >C:\Users\Shuqing\Desktop\log.txt
将日志保存到指定文件。预期结果:日志中不包含敏感信息
整改建议:为了防止信息泄漏,不要在日志中输出敏感数据
安全风险:敏感数据明文存储在手机上增加了信息泄露的风险
执行步骤
apk
安装文件查找是否明文存储用户信息、业务数据、服务信息或其他敏感信息。预期结果:文件中未存放用户或系统敏感信息
整改建议:如果一定要在客户端存放系统敏感数据,建议加密后再存储。
安全风险:应用文件被分配了不合理的权限,导致其他应用可以读取和获取文件内容,增加了内容泄露的风险。
执行步骤
adb shell
连接设备cd /data/data/xxxx(包名)
ls -al
,查看当前目录下所有文件权限。r
代表只读,w
代表写,x
代表可执行,d
表示是一个目录。预期结果:
drwxrwx--x
,允许多一个执行位x
-rw-rw----
),即除应用自己以外任何人无法读写;整改建议
MODE_WORLD_WRITEABLE
(可写)和MODE_WORLD_READABLE
(可读)模式创建进程间通信的文件,如果需要与其他进程应用进行数据共享,请考虑使用content provider
;MODE_PRIVATE
模式创建内部存储文件,默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容。安全风险:敏感数据直接存储在sqlite
数据库导致信息泄露的风险。
执行步骤
/data/data/[package name]/databases/
,查找sqlite
数据库文件并复制到PC端DB.Browser.for.SQLite
打开sqlite
文件。预期结果:客户端数据库文件中不存在敏感数据。
整改建议:如果一定要在客户端存放系统或系统敏感数据,建议加密后再存储。
安全风险:获取或者篡改app中存储的敏感信息,如手机号、账号、密码等,在业务运行操作时无法保证数据安全。
执行步骤
drozer
连接测试设备run app.provider.info -a appname
run scanner.provider.finduris -a appname
run scanner.provider.injection -a appname
run scanner.provider.traversal -a appname
预期结果 无法获取到相关数据信息。
整改建议 使用参数化查询防御SQL
注入,限制Provider
组件的权限,取消不必要的Provider
组件接口。
WebView
是Android
系统提供能显示Web
页面的系统控件,例如混合类型的App
中H5
界面就是使用了WebView
组件。
安全风险:Webview中接口addJavascriptInterface
可通过webview
对象向页面javascript
导出java
本地接口,可能导致任意命令执行。
执行步骤
settings.setJavaScriptEnabled(true); //设置开启javascript
settings.setJavaScriptCanOpenWindowsAutomatically(true); //设置允许js弹出alert对话框
mWebView.addJavascriptInterface(new JSInvokeClass(), "js2java"); //注入javascript映射
Web
组件远程代码执行的风险。预期结果:系统使用安全接口调用webview
整改建议
addJavascriptInterface
导出Java
类及方法,并加强访问的url
的域控制;安全风险
WebView
的过程中开启了setSavePassword
保存密码,当用户在WebView
中输入的用户名和密码,则会被明文保存到应用。databases/webview.db
中。root
就可以获取明文保存的密码,造成用户的个人敏感数据泄露。执行步骤
mWebView.getSettings().setSavePassword(true); //设置开启保存密码
mWebView.loadUrl("http://www.example.com");
预期结果:在调用setSavePassword
时设定setSavePassword(false)
整改建议:使用WebView.getSettings().setSavePassword(false)
来禁止保存密码
安全风险
Android WebView
组件加载网页发生证书认证错误时,会调用WebViewClient
类的onReceivedSslError
方法,如果该方法实现调用了handler.proceed()
来忽略该证书错误,则会受到中间人攻击的威胁,可能导致隐私泄露。
执行步骤
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(new JsBridge(mContext), JS_OBJECT);
mWebView.loadUrl("http://www.example.org/tests/addjsif/");
mWebView.setWebViewClient(new WebViewClient() {
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
handler.proceed(); //忽略证书错误
}
});
onReceivedSslError
处理时没有进行cancel
,还是使用了proceed()
,忽略掉了发生的SSL
异常。则说明风险存在。记录漏洞,停止测试。预期结果:正确的处理SSL
错误,避免证书错误的风险。
整改建议:当发生证书认证错误时,采用默认的处理方法handler.cancel()
,停止加载问题页面。
安全风险:攻击者可以发送恶意的消息,控制Receiver
执行恶意动作或者造成信息泄露。
执行步骤
Drozer
扫描暴露的broadcast
组件run app.broadcast.info -a xxxx -i
和相关action
信息receiver
组件发送空值,run app.broadcast.send --action xxx
,查看是否能够造成应用程序崩溃,形成拒绝服务。预期结果 系统为Broadcast
组件分配了适当权限。
整改建议 AndroidManifest.xml
文件的各receiver
标签中,设置android:exported="false"
;BroadcastReceiver
代码中增加消息异常处理机制。
安全风险
应用程序在广播包含敏感信息的消息时,由于未指定具体的接收组件,攻击者可能仿冒receiver
来接受来自应用程序的消息,从而窃取敏感信息。
执行步骤
apk
获取源代码,在源代码中搜索定位发送广播消息的位置,例如搜索sendBroadcast()
。Intent
时,是否显式指定了接收该广播的组件名称,以及要发送的广播中是否包含敏感信息。示例代码如下:public class ServerService extends Service {
// ...
private void d() {
// ...
Intent v1 = new Intent();//未显式指定接收组建名称
v1.setAction("com.sample.action.server_running");
v1.putExtra("local_ip", v0.h);
v1.putExtra("port", v0.i);
v1.putExtra("code", v0.g);
v1.putExtra("connected", v0.s);
v1.putExtra("pwd_predefined", v0.r);
if (!TextUtils.isEmpty(v0.t)) {
v1.putExtra("connected_usr", v0.t);
}
}
this.sendBroadcast(v1);
}
3、 如果应用程序未指定接收组件并且广播中包含类似password
等信息,则存在信息泄露的风险。
预期结果 :显式的制定接收组建、并且分配了合适的权限
整改建议
action
与包名intent.setAction("allow.package.recv.action"); //设置指定的action
intent.setPackage("allow.package.recv.packagename"); //设置指定的包名
sendBroadcast(intent); //发送广播
如果指定特殊的receiver
接收可以指定component
:
intent.setComponent(newComponentName("allow.package.recv.packagename", "allow.package.recv.classname"));
sendBroadcast(intent);
LocalBroadcastManager
,使广播的Intent
仅在该进程内部,而不会让同一APP
的其他进程或者其他APP
接收到。API
:sendStickyBroadcast
sendStickyBroadcastAsUser
sendStickyOrderedBroadcast
sendStickyOrderedBroadcastAsUser
Android SDK
文档中也明确说明了存在安全问题, 如果必须使用,广播中不应包含敏感信息,另外需要设置接收权限:
//设置广播权限
sendBroadcast(intent,"broadcast.permission");
//向特定用户发送广播
this.sendBroadcastAsUser(i, null,"broadcast.permission");
this.sendOrderedBroadcastAsUser(i, null, "broadcast.permission", null, null, 0, null, null);
this.sendOrderedBroadcast(i, "broadcast.permission");
this.sendOrderedBroadcast(i, "broadcast.permission", null, null, 0, null, null);
同时在AndroidManifest.xml
中如下配置:
<uses-permission android:name="broadcast.permission" />
<permission android:name="broadcast.permission" android:protectionLevel="signature" />
android:protectionLevel
为signature
,防止其他APP能够非常容易的窃取权限。
安全风险:攻击者可以发送恶意的消息,控制Receiver
执行恶意动作或者造成信息泄露。
执行步骤
registerReceiver()
,查找动态广播接收器。也可以使用命令:run app.broadcast.info -a com.xxxx -i
android:exported="true"
权限的组件。receiver
,找到应用程序定义的在接收到消息时的各项参数以及各种处理逻辑。Broadcast
组件,是否越权进行操作。预期结果:合理分配Broadcast
组件权限
整改建议:
AndroidManifest.xml
文件的receiver
标签中设android:exported="false"
。AndroidManifest.xml
中,申明一个私有权限,级别为signature
;exported='false'
,并且不配置intent-filter
,对接收来的广播进行验证;安全风险:攻击者可以绕过认证阶段,直接调用后续activity
组件。
执行步骤
AndroidManifest.xml
中activity
组件(关注配置了intent-filter
的及未设置export=“false”
的组件)。Drozer
扫描暴露的Activity
:run app.activity.info -a packagename
run app.activity.start --component 包名 Activity名
Activity
能否被正常显示,如果可以则会形成越权、信息泄露等风险。预期结果 设定正确的activity
权限,避免造成越权或信息泄露。
整改建议
Activity
不应配置intent-filter
,如果配置了intent-filter
需设置exported
属性为false
;intent
以及其携带的信息,当Activity
返回数据时候需注意目标Activity
是否有泄露信息的风险;安全风险
APP创建Intent
传递数据到其他Activity
,如果创建Activity
时通过addFlags
设置了FLAG_ACTIVITY_NEW_TASK
,Activity
会在另一个Task
中打开,
这种情况很可能被其他的Activity
劫持读取到Intent
内容,跨Task
的Activity
通过Intent
传递敏感信息是不安全的,会导致intent
中的敏感数据泄露。
执行步骤
FLAG_ACTIVITY_NEW_TASK
标签):Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //设置了FLAG_ACTIVITY_NEW_TASK
startActivity(intent);
Intent i = new Intent("com.xiaomi.mipush.RECEIVE_MESSAGE");
startActivity(i);
FLAG_ACTIVITY_NEW_TASK
标签就存在该风险,记录漏洞,停止测试预期结果:不包含FLAG_ACTIVITY_NEW_TASK
标志的Intent
启动Activity
整改建议:避免使用包含FLAG_ACTIVITY_NEW_TASK
标志的Intent
启动Activity
安全风险: 攻击者可以利用开放的Provider Content
获取系统敏感资源
执行步骤
AndroidManifest.xml
文件,定位各Provider
,尤其是设置了android:exported="true"
的。Drozer
扫描:run scanner.provider.finduris -a com.mwr.example.sieve
Accessible content URIs
说明存在注入风险。预期结果:系统为Content Provider
组件分配合适的权限,不存在信息泄露。
整改建议
AndroidManifest.xml
文件的各provider
标签中,设置android:exported="false"
;minSdkVersion
不低于9
;content provider
交换数据设置protectionLevel=“signature”
验证签名,仅授予那些和本程序应用了相同密钥来签名的程序content provider
确保不存储敏感数据;安全风险
APP的实现中定义了一个可以访问本地文件的Content Provider
组件,默认的android:exported="true"
,该Provider
实现了openFile()
接口
通过此接口可以访问内部存储app_webview
目录下的数据,由于后台未能对目标文件地址进行有效判断,可以通过"../"
实现目录跨越,导致对任意私有数据的访问。
执行步骤
drozer
命令扫描run scanner.provider.traversal -a com.mwr.example.sieve
Vulnerable Providers
说明存在文件遍历风险。预期结果:不存在文件遍历漏洞。
整改建议:系统对在调用文件参数时添加防御。
安全风险:攻击者可以发送恶意的消息,控制Service
执行恶意动作或者造成信息泄露。
执行步骤
drozer
命令 run app.service.info -a xxxx
查看service
组件暴露。service
,找到应用程序定义的在接收到消息时的各项参数以及各种处理逻辑。Service
组件,能否能进行越权操作。如果可以风险存在,停止测试,记录漏洞。预期结果 系统为Service
组件分配了适当权限
整改建议
AndroidManifest.xml
文件的各receiver
标签中,设置android:exported="false"
。AndroidManifest.xml
中,申明一个私有权限,级别为signature
;service
应设置为私有;service
接收到的数据需需谨慎处理,对调用的接口做校验;安全风险:攻击者可以发送恶意的消息,控制Receiver
执行恶意动作或者造成信息泄露。
执行步骤
AndroidManifest.xml
文件,定位各Receiver
,尤其是设置了android:exported="true"
的。run app.service.start --action 服务名 --component 包名 服务名
,查看是否能够造成应用程序拒绝服务。预期结果:系统为Service
组件分配了适当权限
整改建议: AndroidManifest.xml
文件的各组件标签中,设置android:exported="false"
;组件接收消息代码中增加消息异常处理机制。
备注:其他类型的拒绝服务攻击参考SEC_AN_ PLUS_11.1 intent
应用本地拒绝服务漏洞。
安全风险
Android
系统中提供了Intent
机制来协助应用间的交互与通讯,例如:应用A
发出一个intent
信息,系统根据intent
的描述,负责找到可以解析该intent
消息的应用B
。
B
应用负责接收intent
的组件,在解析intent
数据时,会通过Intent
的getXXXExtra()
函数,如果解析为空数据、异常、或是畸形数据,就可能会导致程序崩溃。
执行步骤
Intent
传入自定义的序列化对象,被攻击者在组件里解析该序列化数据,可能出现出现找不到类出现ClassNotFoundException
异常而崩溃。攻击代码如下:Intent intent = new Intent();
intent.setAction("serializable_action");
intent.setClassName("com.my.test", "com.my.test.MainActivity"); // 指定攻击目标的包名和Activity入口
intent.putExtra("serializable_obj",XXX); //此处是传入畸形数据
startActivity(intent);
IndexOutOfBoundsException
异常导致的拒绝服务,如果程序没有对getIntegerArrayListExtra()
等获取到的数据数组元素大小的判断,从而导致数组访问越界而导致应用崩溃;攻击应用代码片段:Intent intent = new Intent();
intent.setClassName("com.alibaba.jaq.pocforrefuseservice", "com.alibaba.jaq.pocforrefuseservice.MainActivity");
ArrayList<Integer> user_id = new ArrayList<Integer>(); //定义数组
intent.putExtra("user_id", user_id);
startActivity(intent);
)
预期结果:在使用Intent
获取数据时对异常做了充分的处理。
整改建议
建议处理通过Intent.getXXXExtra()
获取的数据时进行以下判断,以及用try catch
方式进行捕获所有异常,以防止应用出现拒绝服务漏洞:
安全风险
Android应用通常使用PF_UNIX、PF_INET、PF_NETLINK
等不同域名的socket
来进行本地进程间通信或者远程网络通信,这些socket
暴漏了潜在的本地或远程攻击面,历史上也出现过不少利用socket
进行拒绝服务、root
提权或者远程命令执行的案例。
特别是PF_INET
类型的网络socket
,可以通过网络与Android
应用通信,其原本用于linux
环境下开放网络服务,由于缺乏对网络调用者身份或者本地调用者的安全检查机制,在实现不当的情况下,可以突破Android
的沙箱限制,对被攻击的应用执行命令,导致比较严重的漏洞。
执行步骤
socket
数据是否进行处理,代码示例如下://定义读取socket命令
public static String readCMDFromSocket(InputStream in) {
int MAX_BUFFER_BYTES = 2048;
String msg = "";
byte[] tempbuffer = new byte[MAX_BUFFER_BYTES];
try {
int numReadedBytes = in.read(tempbuffer, 0, tempbuffer.length);
if( numReadedBytes > -1 )
msg = new String(tempbuffer, 0, numReadedBytes, "utf-8");
tempbuffer = null;
} catch (Exception e) {
e.printStackTrace();
}
return msg;
}
...
//处理socket信息
public void handlemsg()
{
...
msg = readCMDFromSocket(in)
if ("exec" == msg)
{
//没有任何的socket命令校验
...
...
}
...
}
socket
和内容做任何校验检查,则风险存在。预期结果 对socket
数据内容进行校验。
整改建议 直接传递命令或者间接处理敏感信息时,避免使用socket
实现。
安全风险
APP中使用了有运行其他程序的代码逻辑,如果执行的代码是第三方库中,可能会存在未知的恶意行为,如果是程序自身代码,若调用逻辑有缺陷可能会导致执行其他恶意的第三方程序,攻击者可能会利用该缺陷执行恶意代码。
执行步骤
Runtime.getRuntime().exec
执行第三方程序的代码样例:try {
Process p1 = Runtime.getRuntime().exec(
new String[] { "/system/bin/ls", "-l" },
new String[] { "a=1", "b=2" });
Runtime.getRuntime().load(
"/data/data/com.baidu.seclab/lib/libtest.so");
Runtime.getRuntime().loadLibrary("test");
} catch (IOException e) {
e.printStackTrace();
}
Runtime.getRuntime().exec
执行第三方程序后,且检测到调用逻辑中存在缺陷,则风险存在。停止测试,记录漏洞。预期结果 合理使用Runtime.getRuntime().exec
等函数,防止恶意调用。
整改建议 合理设置程序逻辑防止恶意调用,如果该行为是非期望行为,移除相关代码。
安全风险
App向服务器提交的数据易被中间人篡改,对用户数据的完整性造成影响,如用户信息被破解利用等问题。
执行步骤
Charles
代理工具连接设备代理,启动app,正常操作app;预期结果:请求数据中包含完整性校验字段;
整改建议:添加完整性校验逻辑。
安全风险:
攻击者可以通过劫持键盘窃取用户输入数据,可能带来用户账号密码、敏感数据等泄露的风险,特别是银行金融类App。
执行步骤
预期结果:App在输入时使用自带键盘
整改建议:在App内集成自带键盘,并采用随机分布式键盘。