鉴于目前国内app安全方面抓的越来越紧,不仅apk会拿去做安全检测,apk的源码也是拿去做相关的安全检测。这无疑中给我们开发增加了不少工作量,以下就列举了一些博主开发时被检测出来的代码漏洞。
详细信息:
Android API level 16以及之前的版本存在远程代码执行安全漏洞,该漏洞源于程序使用
WebView.addJavascriptInterface
可以实现网页JS与本地JAVA的交互,但是没有限制已注册
JAVA类的方法调用,类中的任何public函数都可以在JS代码中访问,这就导致可以调用
getClass
通过java反射机制来执行任意Java对象的方法。
例如:利用addJavascriptInterface
方法注册可供JavaScript调用的Java对象
injectedObj
,利用反射机制调用Android API getRuntime
执行shell命令:
java代码:
...
WebView webView1 = (WebView)findViewById(R.id.webView1);
JavaScriptInterface myJavaScriptInterface = new JavaScriptInterface();
webView1.addJavascriptInterface(myJavaScriptInterface,"injectedObj");
webView1.loadUrl("http://www.example.com");
...
js代码:
<html>
<body>
<script>
function execute(cmdArgs) {
return
injectedObj.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,n
ull).exec(cmdArgs);
}
var res = execute(["/system/bin/sh", "-c", "ls -al /mnt/sdcard/"]);
document.write(getContents(res.getInputStream()));
script>
body>
html>
修复建议:
1.避免调用addJavascriptInterface()
方法(如果只是展示页面数据,而不做数据通信,完全可以不使用),或者将API等级设为17或者更高级别,对于这
些API等级,只有被标注了JavascriptInterface
的公共方法才可以从JavaScript访问。
2.webview组件会默认内置一个searchBoxJavaBridge_
接口,故需要使用
removeJavascriptInterface
移除searchBoxJavaBridge_
。
3.调用了Android/webkit/AccessibilityInjector
组件的应用在开启辅助功能选项中第三方服务
的安卓系统会默认添加accessibility
和accessibilityTraversal
接口,同样需要使用
removeJavascriptInterface
进行移除。
详细信息:
采用SSL进行连接时,使用AllowAllHostnameVerifier()
和
SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER
将会关闭主机名验证功能。这相
当于信任所有证书。
例如:下列代码SSLSocketFactory调用setHostnameVerifier
方法,将
SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER
作为参数,将会关闭主机名验证
功能。
...
KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType());
store.load(null, null);
SSLSocketFactory sf = new SSLSocketFactory(store);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));
ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
...
修复建议:
采用SSL连接时,不应放弃服务器验证检查。可考虑采用StrictHostnameVerifer建立服务
器身份和安全SSL连接。
详细信息:
应用程序如果通过共享存储安装应用程序,如果攻击者使用恶意应用程序将下载的
APK文件替换为恶意APK文件,安装进程会使用该恶意APK文件取代合法APK。
例如:在以下代码片段中,通过共享存储安装应用程序。
Intent myIntent = new Intent(Intent.ACTION_VIEW);
Uri apkUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/download/" +
"install.apk")), "application/vnd.android.package-archive");
myIntent.setDataAndType(apkUri);
myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
myContext.startActivity(intent);
修复建议:
检查代码逻辑,不要共享存储安装应用程序,防止被替换为恶意文件。
以上检测的是android7.0以下的写法,在android7.0以上使用的是FileProvider.getUriForFile来获取Uri(这是安全的),这算是以前老系统的一个漏洞了。而为了适配7.0以下的系统,必须得使用Uri.fromFile,可以在代码检测时先把这句话注释掉。因为代码检测并不智能,所以只能暂时这么做
if (Build.VERSION.SDK_INT >= 24) {
File file = new File(pathstr);
//参数1 上下文, 参数2 Provider主机地址 和配置文件中保持一致 参数3 共享的文件
Uri apkUri = FileProvider.getUriForFile(mContext, "com.dlwq.android.file.provider", file);
//添加这一句表示对目标应用临时授权该Uri所代表的文件
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
} else {
// intent.setDataAndType(Uri.fromFile(new File(mContext.getExternalCacheDir(), name)), "application/vnd.android.package-archive");
}
详细信息:
反射型XSS是指应用程序通过Web请求获取不可信赖的数据,并在未检验数据是否存在
恶意代码的情况下,将其发送给用户。反射型XSS一般可以由攻击者构造带有恶意代码参
数的URL来实现,在构造的URL地址被打开后,其中包含的恶意代码参数被浏览器解析
和执行。这种攻击的特点是非持久化,必须用户点击包含恶意代码参数的链接时才会触
发。
例如:下面JSP代码片段的功能是从HTTP请求中读取输入的用户名(username)并显示
到页面。
<%
String name= request.getParameter("username"); %>
...
姓名: <%= name%>
...
如果name里有包含恶意代码,那么Web浏览器就会像显示HTTP响应那样执行该代码,应
用程序将受到反射型XSS攻击。
修复建议:
为了避免反射型XSS攻击,建议采用以下方式进行防御:
1.对用户的输入进行合理验证(如年龄只能是数字),对特殊字符(如<、>、'、"
以及