(转载)JS与WebView交互存在的一些问题
JS与WebView交互存在的一些问题
一、背景概述
2013年Android平台暴露出WebView漏洞。利用该漏洞,攻击者可以通过存在风险的addJavascriptInterface接口函数提供的扩展穿透webkit执行本地Java代码,造成恶意代码在受害人的手机上执行,并可能进一步执行木马。
目前,google公司仅对Android4.2及以上系统提供了规避方法,Android4.2以下所有版本尚无官方解决方案。
本文将就上述漏洞提出相应的解决方案。
Android API level 16以及之前的版本存在远程代码执行安全漏洞,该漏洞源于程序没有正确限制使用WebView.addJavascriptInterface方法,远程攻击者可通过使用Java Reflection API利用该漏洞执行任意Java对象的方法,简单的说就是通过addJavascriptInterface给WebView加入一个JavaScript桥接接口,JavaScript通过调用这个接口可以直接操作本地的JAVA接口。
该漏洞公布的近期,多款Android流行应用曾被曝出高危挂马漏洞:点击消息或朋友社区圈中的一条网址时,用户手机然后就会自动执行被挂马的代码指令,从而导致被安装恶意扣费软件、向好友发送欺诈短信、通讯录和短信被窃取以及被远程控制等严重后果。在乌云漏洞平台上,包括Android版的微信、QQ、腾讯微博、QQ浏览器、快播、百度浏览器、金山浏览器等大批TOP应用均被曝光同类型的漏洞。
不可避免,由于公司中,修旧并行的架构中,涉及很多的WebView和JS交互的功能实现点。安全部已经发布方案,需要我们修改。最近一直在做这方面的研究。
引用:【http://blog.csdn.net/leehong2005/article/details/11808557#】
使用WebView来展示一个网页,现在很多应用为了做到服务端可控,很多结果页都是网页的,而不是本地实现,这样做有很多好处,比如界面的改变不需要重新发布新版本,直接在Server端修改就行了。用网页来展示界面,通常情况下都或多或少都与Java代码有交互,比如点击网页上面的一个按钮,我们需要知道这个按钮点击事件,或者我们要调用某个方法,让页面执行某种动作,为了实现这些交互,我们通常都是使用JS来实现,而WebView已经提供了这样的方法,具体用法如下:< mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(new JSInterface(), "jsInterface");>
我们向WebView注册一个名叫“jsInterface”的对象,然后在JS中可以访问到jsInterface这个对象,就可以调用这个对象的一些方法,最终可以调用到Java代码中,从而实现了JS与Java代码的交互。
我们一起来看看关于addJavascriptInterface方法在Android官网的描述:
This method can be used to allow JavaScript to control the host application. This is a powerful feature, but also presents a security risk for applications targeted to API level JELLY_BEAN
or below, because JavaScript could use reflection to access an injected object's public fields. Use of this method in a WebView containing untrusted content could allow an attacker to manipulate the host application in unintended ways, executing Java code with the permissions of the host application. Use extreme care when using this method in a WebView which could contain untrusted content.
JavaScript interacts with Java object on a private, background thread of this WebView. Care is therefore required to maintain thread safety.
The Java object's fields are not accessible.
简单地说,就是用addJavascriptInterface可能导致不安全,因为JS可能包含恶意代码。今天我们要说的这个漏洞就是这个,当JS包含恶意代码时,它可以干任何事情。
二、实现方案
1、Android 4.2以上的系统
Android 4.2以上系统,通过在Java的远程方法上面声明@JavascriptInterface可以解决WebView漏洞。如下面代码:
class JsObject {
@JavascriptInterface
public String toString() { return "injectedObject"; }
}
2、Android 4.2以下的系统
若客户端需要兼容支持Android 4.2以下的系统版本,建议使用本方案规避WebView漏洞。本方案分为两个修改要点,建议对于https和http场景均使用下述方法规避风险。
修改点一:使用安全方法替代addJavascriptInterface
对于Android 4.2以下的系统Google公司官方没有提供解决方案。为替代addJavascriptInterface方法,可以利用prompt方法传参以完成java与js的交互。对应java中的onJsPrompt方法的声明如下:public boolean onJsPrompt( WebView view, String url, String message, String defaultValue, JsPromptResult result )
通过这个方法,JS能把信息(文本)传递到Java,而Java也能把信息(文本)传递到JS中。
具体实施方法如下:
1)让JS调用一个Javascript方法,在这个方法中调用prompt方法,通过prompt把JS中的信息传递过来,这些信息应该是我们组合成的一段有意义的文本,可能包含:特定标识,参数等。在onJsPrompt方法中,我们去解析传递过来的文本,得到约定好的特定标识,参数等,再通过特定标识调用指定的java方法,并传入参数。具体的Java代码如下:
final class MyWebChromeClient extends WebChromeClient
{
public boolean onJsPrompt( WebView view, String url, String message, String defaultValue, JsPromptResult result )
{
if( message.equals("1") )
{
//解析参数defaultValue
//调用java方法并得到结果
}
//返回结果
result.confirm("result");
return true;
}
}
2)关于返回值,可以通过result返回回去,这样就可以把Java中方法的处理结果返回到Js中。
3)在Javascript方法中,通过调用prompt方法传入标识和参数(依次对应onJsPrompt方法中的message、defaultValue参数),以通知java需要使用的方法及对应参数。prompt方法中第一个参数可以传送约定好的特定方法标识,prompt方法中第二个参数可以传入对应的参数序列。具体的Javascript代码如下:
function showHtmlcallJava()
{
var ret = prompt( "1", "param1;param2" );
//ret值即为java传回的”result”
//根据返回内容作相应处理
}
修改点二:移除系统开放的JS接口
对于Android 3.0以上版本,Android系统开放了部分JS接口。因此在这个版本范围下,尽管客户端自身没有使用addJavascriptInterface方法,黑客仍可以透过系统开放的JS接口实施恶意操作。
针对上述风险,客户端可通过下面的方法移除风险接口。具体实施方法如下:
1)使用removeJavascriptInterface方法移除操作系统开放的"searchBoxJavaBridge_"、"accessibility"、"accessibilityTraversal"接口。由于removeJavascriptInterface方法只在Android API 11以上版本支持,因此若客户端需要支持Android API 11以下版本,需要在使用该方法时声明目标API。@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void dealJavascriptLeak() {
mWebView.removeJavascriptInterface("searchBoxJavaBridge_");
mWebView.removeJavascriptInterface("accessibility");
mWebView.removeJavascriptInterface("accessibilityTraversal");
}
2)针对Android3.0以上系统版本移除问题接口。if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
dealJavascriptLeak();
}
三、总结
对于https和http协议访问的页面,开发过程中须注意弃用存在漏洞的addJavascriptInterface方法,通过使用prompt方法传参,完成java与js的交互。同时客户端须移除系统开放的JS接口,全面规避WebView漏洞风险。
详细修步骤:
【1】让JS调用一个Javascript方法,这个方法中是调用prompt方法,通过prompt把JS中的信息传递过来,这些信息应该是我们组合成的一段有意义的文本,可能包含:特定标识,方法名称,参数等。在onJsPrompt方法中,我们去解析传递过来的文本,得到方法名,参数等,再通过反射机制,调用指定的方法,从而调用到Java对象的方法。
【2】关于返回值,可以通过prompt返回回去,这样就可以把Java中方法的处理结果返回到Js中。
【3】我们需要动态生成一段声明Javascript方法的JS脚本,通过loadUrl来加载它,从而注册到html页面中,具体的代码如下:
javascript:(function JsAddJavascriptInterface_(){
if (typeof(window.jsInterface)!='undefined') {
console.log('window.jsInterface_js_interface_name is exist!!');}
else {
window.jsInterface = {
onButtonClick:function(arg0) {
return prompt('MyApp:'+JSON.stringify({obj:'jsInterface',func:'onButtonClick',args:[arg0]}));
},
onImageClick:function(arg0,arg1,arg2) { prompt('MyApp:'+JSON.stringify({obj:'jsInterface',func:'onImageClick',args:[arg0,arg1,arg2]}));
},
};
}
}
)()
说明:
1,上面代码中的jsInterface就是要注册的对象名,它注册了两个方法,onButtonClick(arg0)和onImageClick(arg0, arg1, arg2),如果有返回值,就添加上return。
2,prompt中是我们约定的字符串,它包含特定的标识符MyApp:,后面包含了一串JSON字符串,它包含了方法名,参数,对象名等。
3,当JS调用onButtonClick或onImageClick时,就会回调到Java层中的onJsPrompt方法,我们再解析出方法名,参数,对象名,再反射调用方法。
4,window.jsInterface这表示在window上声明了一个Js对象,声明方法的形式是:方法名:function(参数1,参数2)
5,一些思考
以下是在实现这个解决方案过程中遇到的一些问题和思考:
【1】生成Js方法后,加载这段Js的时机是什么?
刚开始时在当WebView正常加载URL后去加载Js,但发现会存在问题,如果当WebView跳转到下一个页面时,之前加载的Js就可能无效了,所以需要再次加载。这个问题经过尝试,需要在以下几个方法中加载Js,它们是WebChromeClient和WebViewClient的方法:
· onLoadResource
· doUpdateVisitedHistory
· onPageStarted
· onPageFinished
· onReceivedTitle
· onProgressChanged
目前测试了这几个地方,没什么问题,这里我也不能完全确保没有问题。
【2】需要过滤掉Object类的方法
由于通过反射的形式来得到指定对象的方法,他会把基类的方法也会得到,最顶层的基类就是Object,所以我们为了不把getClass方法注入到Js中,所以我们需要把Object的公有方法过滤掉。这里严格说来,应该有一个需要过滤方法的列表。目前我的实现中,需要过滤的方法有:
"getClass",
"hashCode",
"notify",
"notifyAll",
"equals",
"toString",
"wait",
【3】通过手动loadUrl来加载一段js,这种方式难道js中的对象就不在window中吗?也就是说,通过遍历window的对象,不能找到我们通过loadUrl注入的js对象吗?
关于这个问题,我们的方法是通过Js声明的,通过loadUrl的形式来注入到页面中,其实本质相当于把我们这动态生成的这一段Js直接写在Html页面中,所以,这些Js中的window中虽然包含了我们声明的对象,但是他们并不是Java对象,他们是通过Js语法声明的,所以不存在getClass之类的方法。本质上他们是Js对象。
【4】在Android 3.0以下,系统自己添加了一个叫searchBoxJavaBridge_的Js接口,要解决这个安全问题,我们也需要把这个接口删除,调用removeJavascriptInterface方法。这个searchBoxJavaBridge_好像是跟google的搜索框相关的。
【5】在实现过程中,我们需要判断系统版本是否在4.2以下,因为在4.2以上,Android修复了这个安全问题。我们只是需要针对4.2以下的系统作修复。
(转载)JS与WebView交互存在的一些问题的更多相关文章
- android 从 phonegap 到 js webview 交互
像生活类.办公协同类. 动态添加,下载等. 1.phonegap 我这里用了旧的版本,可能新版本变化大了. 创建asset资源文件夹,然后新建index.html copy 相应的js 文件进来. 创 ...
- 转载 【iOS开发】网页JS与OC交互(JavaScriptCore) OC ----->JS
目标 本文介绍利用苹果在iOS7时发布的JavaScriptCore.framework框架进行js与OC的交互.我们想要达到的目标是: OC调用网页上的js方法 网页js调用APP中的OC方法 ...
- js与android webview交互
0x01 js调用java代码 android webview中支持通过添加js接口 webview.addJavascriptInterface(new JsInteration(), " ...
- 转载 ---原生和H5交互挺多的,最近也有朋友再问。这儿我写个简单的例子给大家 直接贴代码 js的
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> ...
- js与native交互
js与native交互 UIWebView Native调用JS,使用stringByEvaluatingJavaScriptFromString来解释执行js脚本. //script即为要执行的js ...
- js与C++交互及C++解析json
转载:http://zhidao.baidu.com/link?url=LLuWzwMmpfVcQeSGv1CrAfRXpnZaetm9xypqwMW6zxLhhKES-rITAsG0-Ku-bSMA ...
- OC和JS之间的交互
OC和JS之间的交互 目录 对OC和JS之间交互的理解 JS调用OC OC调用JS 对OC和JS之间交互的理解 JS调用OC JS文件 function sendCommand(cmd,param){ ...
- 史上最全的 UIWebview 的 JS 与 OC 交互
来源:伯乐在线 - 键盘风筝 链接:http://ios.jobbole.com/89330/ 点击 → 申请加入伯乐在线专栏作者 其实一直想给大家整理一下JS与OC的交互,但是没有合适的机会,今天借 ...
- UIWebView与JS的深度交互
我要实现这样一个需求:按照本地的CSS文件展示一串网络获取的带HTML格式的只有body部分的文本,需要自己拼写完整的 HTML.除此之外,还需要禁用获取的HTML文本中自带的 < img &g ...
随机推荐
- 双系统下Ubuntu安装教程
一.下载Ubuntu镜像包 二.用老毛桃制作U盘启动盘 三.下载Universal USB Installer 下载后无需安装,直接运行Universal USB Installer, step1: ...
- 编写高质量的Makefile
源地址 :http://blog.csdn.net/maopig/article/details/6801749 一.前言 回想自己的第一个Makefile,是这个样子的 CODE hello:hel ...
- Spark SQL概念学习系列之性能调优
不多说,直接上干货! 性能调优 Caching Data In Memory Spark SQL可以通过调用sqlContext.cacheTable("tableName") 或 ...
- layui表格的新增和编辑功能前端代码
html页面的代码(注意:引入layui相关的css): <div class="layui-form-item"> <label class="lay ...
- Android接口回调的理解
1.各种理解 <1>说白了,就是拿到对象引用,调其方法 <2>实际上就是利用多态的方式调用而已 <3>其实很容易理解的,定义接口,然后提供一个外部的接口设置进去,然 ...
- 关于获取WebForm控件的问题
遇到这样的一个问题: 在GridView加载了数据之后,GridView的个别列被设置为TextBox单元格,就是可以修改数量了,单价什么的: 这样就触发了TextChanged事件: 现在要记录谁修 ...
- uni-app 自定义扫码界面
二维码扫描,已经成为当下一款应用不可或缺,同时也是用户习以为常的功能了.uni-app 为我们提供了扫码 API ,直接调用即可. 需求场景 在实际开发中,平台提供的默认扫码界面,并不能满足一些自定义 ...
- 解决JSP页面中文乱码插入到数据库的问题
在JSP页面使用表单注册一个用户名的时候,查看到数据库里面的表中文显示乱码的情况有两种: 1.JSP页面传进来的参数中文就是乱码,则是前台的问题,这个时候写一个过滤器就好了,可以写如下的一个过滤器 p ...
- css——权重叠加
权重叠加 在下面的一段代码中,第一个样式body b有两个标签,第二个有一个标签b.两个中都有color,会应用哪一个呢?果是 那下面的代码会显示什么样的结果 结果是 应用的事body b中的colo ...
- css——样式的优先级
样式的优先级 在p中有id,class,标签,行内样式,它们的优先级: 1.id 样式>class样式>标签样式 2.行内样式>内嵌样式>外部样式 强制优先级 比如我希望上面的 ...