JS和安卓的常见漏洞和解决方法
1、 JS调用的安卓方法必须放在一个Handler中执行
2、 webview可能造成漏洞,调用时分三种:
- addJavascriptInterface 进行js调用, 4.2以下有漏洞
- 使用WebViewClient的shouldOverrideUrlLoading 进行url拦截,缺点是单向请求,有返回值的必须在通过js方法进行返回,适合于页面转换无返回值的情况
- 重写WebViewClient 的 onJsAlert (弹框)、onJsConfirm(是否) 、onJsPrompt(得到返回值) 三个方法进行url判断
3、webview 常见漏洞:
- CVE-2012-6636 (Android4.2 以下): WebView 中 addJavascriptInterface 接口会引起远程代码执行漏洞 ,解决办法:不使用addJavascriptInterface
- CVE-2013-4710 (Android4.2以下): 针对某些特定机型会存在 addJavascriptInterface API 引起的远程代码执行漏洞,解决办法:不使用 addJavascriptInterface
- CVE-2014-1939 (Android4.4 以下): WebView 中的 “searchBoxJavaBridge_” Java Object 可能被利用,实现远程任意代码 ,解决方法 webView.removeJavascriptInterface("searchBoxJavaBridge_");
- CVE-2014-7224 (Android4.4 以下): WebView 中的 “accessibility” 和 “accessibilityTraversal” 两个 Java Object 接口,可被利用实现远程任意代码执行 解决方法 参照 CVE-2014-1939
- WebView 密码明文存储漏洞 : mWebView.setSavePassword(true),如果该功能未关闭,当弹出提示框询问用户是否保存密码选择是以后,密码就被明文存储到安装路径下,所以应该设置为false
- WebView 域控制不严格漏洞 :
setAllowFileAccess(true) // 是否允许 WebView 使用 File 协议 , 在 File 域下,能够执行任意的 JavaScript 代码
setAllowFileAccessFromFileURLs // 是否允许通过 file url 加载的 Javascript 读取其他的本地文件,android 4.1以下默认允许, android 4.1以默认禁止
setAllowUniversalAccessFromFileURLs // 设置是否允许通过 file url 加载的 Javascript 可以访问其他的源 android 4.1以下默认允许, android 4.1以默认禁止综上,使用以下配置让webview可以访问本地html文件,同时杜绝其中的js访问本地文件或者读取其他的源
setAllowFileAccess(true); //设置为 false 将不能加载本地 html 文件 setAllowFileAccessFromFileURLs(false); setAllowUniversalAccessFromFileURLs(false);
-
使用符号链接跨源:当webview 不能访问本地文件和读取其他源以后,其中的js还是能访问当前文件,通过 javascript 的延时执行和将当前文件替换成指向其它文件的软链接就可以读取到被符号链接所指的文件,前提是允许 file URL 执行 javascript,解决办法
-
1、对于不需要使用 file 协议的应用,禁用 file 协议;
setAllowFileAccess(false); //设置为 false 将不能加载本地 html 文件
setAllowFileAccessFromFileURLs(false);
setAllowUniversalAccessFromFileURLs(false);
2、根据不同情况不同处理(无法避免应用对于无法加载的页面下载到 sd 卡上这个漏洞):
setAllowFileAccess(true); //设置为 false 将不能加载本地 html 文件
setAllowFileAccessFromFileURLs(false);
setAllowUniversalAccessFromFileURLs(false);
if (url.startsWith("file://") { setJavaScriptEnabled(false); } else { setJavaScriptEnabled(true); }