一、Android中WebView的漏洞分析
最近在开发过程中遇到一个问题,就是WebView使用的时候,还是需要解决之前系统(4.2之前)导致的一个漏洞,虽然现在这个系统版本用户很少了,但是也不能忽视,关于这个漏洞,这里就不多做解释了,可能有的同学早就了解了,本来想写一篇文章详细介绍一下,但是网上的知识太多了,而且都很详细,就没弄了,这里大致简单明了的说几句:
第一、漏洞产生的原因
这个漏洞导致的原因主要是因为Android中WebView中的JS访问本地方法的方式存在缺陷,我们做过交互的都知道,Android中的交互方式是通过WebView的一个方法:
addJavascriptInterface(new JSObject(), "myObj");
第一个参数:Android本地对象;第二个参数就是JS代码中需要使用的对象
所以这里看其实就相当于一个映射关系,把Android中的本地对象和JS中的对象关联即可。
那么这里就存在这样的一个问题了,在4.2系统之前,JS中通过对象调用的方法无需任何注解约束,那么就意味着JS中拿到这个对象,就可以调用这个对象中所有的方法,而我们知道Android中的对象有一个公共的方法getClass()方法,而这个方法可以获取到当前类类型Class,而这个类型有一个很关键的方法就是Class.forName,这个方法可以加载一个类,这里可以加载Java.lang.Runtime这个类,而这个类就可以执行本地命令了,那么就会发生危险了,比如这里可以执行命令获取本地设备的SD卡中的文件等信息,非常危险的。
上面可能说的还是有些同学不太了解,下面就用一段简单的JS代码来了解一下:

看到这段JS之后的同学应该好理解了,因为我们Android本地通过WebView进行了对象映射,那么WebView加载页面中如果包含这段JS代码,那么就会存在这个问题,这里先遍历window中所有的对象,然后查找这个对象是否有getClass方法,有的话就在利用反射调用Runtime类执行具体命令即可。其实这个漏洞也得力于JS中的语法特性,这里可以看到JS语法非常的灵活。

第二、漏洞修复
当然对于Android4.2之后系统修复了这个漏洞,修复方法也很简单,加上注解约束:@JavascriptInterface 就是只有加上这个注解的方法才会被JS调用,那么我们知道getClass是Object类中的,肯定没有这个注解,那么上面的JS代码肯定执行不到了。就这样解决了这个漏洞。
还有一个问题,就是Android系统默认的会给WebView添加一个JS映射对象:searchBoxJavaBridge_ 这个对象是Android3.0之后默认加上去的,也就是说通过这个对象也是可以操作的上面的代码的。

二、WebView的JS代码和本地代码交互方式
说完了,这个漏洞,下面开始说今天的正题了,为什么要先介绍这个漏洞呢?原因就是如果要在4.2以下版本中解决这个漏洞的话就需要借助今天介绍的内容了,首先来看看今天的内容主要是介绍Android中WebView的JS和本地交互的三种方式:
第一种方式:通过addJavascriptInterface方法进行添加对象映射
这种方式不多解释了,也是Android中最常用的方式,但是这种方式会存在风险就是上面说到的漏洞问题。

这里定义一个简单的本地对象,在需要被调用的方法加上约束注解。JS代码也很简单:

这种方式的好处在于使用简单明了,本地和JS的约定也很简单,就是对象名称和方法名称约定好即可,缺点就是存在漏洞问题。

第二种方式:利用WebViewClient接口回调方法拦截url
这种方式其实实现也很简单,就是我们可以添加WebViewClient回调接口,在shouldOverrideUrlLoading回调方法中拦截url,然后解析这个url的协议,如果发现是我们约定好的协议就开始解析参数执行具体逻辑:

代码也很简单,这个方法可以拦截WebView中加载url的过程,得到对应的url,我们就可以通过这个方法,和网页JS约定好一个协议,看一下JS代码:

这个JS代码执行之后,就会触发本地的shouldOverrideUrlLoading方法,然后进行参数解析,调用指定方法。
这个方法是不会存在第一种方法的漏洞问题,但是细心的同学可以发现,这里本地和JS之间的约定有点繁琐,比如要约定好协议,参数名称等信息,没有第一种方式方便。而且最主要的问题是,这个只能主动的调用本地化方法,如果想得到方法的返回值,只能通过WebView的loadUrl方法去执行JS方法,把返回值传递回去:mWebView.loadUrl("JavaScript:clicktworesult("+res+")");

看到这种方式是非常繁琐的。在Android中也是不提倡使用的。
注意:在iOS中没有像Android中的第一种方式,他也是为了安全考虑,所以iOS中的交互就是采用的第二种方式,通过拦截url来进行操作的,当时候介绍iOS这部分内容的时候在详细介绍。

第三种方式:利用WebChromeClient回调接口的三个方法拦截消息
这个方法的原理其实和第二种方式差不多,只是拦截的接口方法不一样:

Android中的WebView添加WebChromeClient接口,可以拦截JS中的几个提示方法,也就是几种样式的对话框,在JS中有三个常用的对话框方法:
1. alert是弹出警告框,在文本里面加入\n就可以换行。
2. confirm弹出确认框,会返回布尔值,通过这个值可以判断点击时确认还是取消。true表示点击了确认,false表示点击了取消。
3. prompt弹出输入框,点击确认返回输入框中的值,点击取消返回null。
那么这三种对话框都是可以在本地拦截到的,那么第三种方法的原理就是拦截这些方法,得到他们的消息内容,然后解析即可,比如这里我们拦截了prompt方法内容:

本地拦截的方法参数说明:

为什么要拦截prompt方法,因为这个方法可以返回想要的值,而对于alert是无法得到返回值的,confirm只能得到两个返回值。只有prompt方法可以返回各种类型的值,操作最方便。
然后在这个方法中和第二种方法一样的原理解析消息内容即可

三、执行结果
下面直接看看上面的三种方式的执行效果:
第一种方式:

第二种方式:

第三种方式:

其中html代码如下:

四、三种方式总结
好了,到这里我们就介绍完了Android中WebView的JS和本地交互的三种方式:
第一种方式:是最普遍的用法,方便简单,但是在4.2系统以下存在漏洞问题
第二种方式:是通过拦截url,解析约定之后的协议调用本地方法,缺点是约束协议比较繁琐,而且传回执行之后的返回值比较麻烦。但是不会存在漏洞问题,而这种方式也是iOS中采用的方式。
第三种方式:其实和第二种方式差不多,只是拦截的方法变了,这里拦截的是JS中的三种对话框方法,而这三种对话框方法的区别就在于返回值问题,alert对话框方法没有返回值,confirm对话框方法只有两种状态的返回值,prompt对话框方法可以返回任意类型的返回值。缺点和第二种方法一样,协议约定比较繁琐,但是不会存在漏洞问题。

五、关于4.2以下的WebView漏洞修复策略
最后在来介绍一下文章中开始介绍的漏洞问题,虽然google在4.2之后修复了这个漏洞,但是对于4.2之前的用户该如何处理这个漏洞呢?这里主要就是需要借助第三种方式了,拦截prompt方法,修复步骤很简单:
1、我们自己显示一个WebView的包装器,重写他的addJavascriptInterface方法,然后在内部自己维护一个对象映射关系Map

2、在WebView加载页面的方法中构造一段本地JS代码:

关于这段JS代码的含义:
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)
而加载这段JS代码的时机是什么时候呢?
刚开始时在当WebView正常加载URL后去加载Js,但发现会存在问题,如果当WebView跳转到下一个页面时,之前加载的Js就可能无效了,所以需要再次加载。这个问题经过尝试,需要在以下几个方法中加载Js,它们是WebChromeClient和WebViewClient的方法:onLoadResource,doUpdateVisitedHistory,onPageStarted,onPageFinished,onReceivedTitle,onProgressChanged

3、让JS调用一个Javascript方法,这个方法中是调用prompt方法,通过prompt把JS中的信息传递过来,这些信息应该是我们组合成的一段有意义的文本,可能包含:特定标识,方法名称,参数等。www.xinbaovip.cn 在onJsPrompt方法中,我们去解析传递过来的文本,得到方法名,参数等,再通过反射机制,调用指定的方法,从而调用到Java对象的方法。

4、关于返回值,可以通过prompt返回回去,这样就可以把Java中方法的处理结果返回到Js中。

通过这几步,就可以简单的修复漏洞问题,但是还是需要注意几个问题:
1> 需要过滤掉Object类的方法由于通过反射的形式来得到指定对象的方法,他会把基类的方法也会得到,最顶层的基类就是Object,所以我们为了不把getClass方法注入到Js中,所以我们需要把Object的公有方法过滤掉。这里严格说来,应该有一个需要过滤方法的列表。目前我的实现中,需要过滤的方法有:
"getClass","hashCode","notify","notifyAll","www.zhengly.cn equals","toString","wait",

2> 在Android 3.0以下,系统自己添加了一个叫searchBoxJavaBridge_的Js接口,要解决这个安全问题,我们也需要把这个接口删除,调用removeJavascriptInterface方法。这个www.yyzx66.cn/ searchBoxJavaBridge_好像是跟google的搜索框相关的。

3> 在实现过程中,我们需要判断系统版本是否在4.2以下,因为在4.2以上,Android修复了这个安全问题。我们只是需要针对4.2以下的系统作修复。

Android中WebView的JavaScript代码和本地代码交互的三种方式的更多相关文章

  1. Android自动化测试中AccessibilityService获取控件信息(2)-三种方式对比

    Android自动化测试中AccessibilityService获取控件信息(2)-三种方式对比   上一篇文章: Android自动化测试中AccessibilityService获取控件信息(1 ...

  2. android解析XML总结(SAX、Pull、Dom三种方式) <转载>

    android解析XML总结(SAX.Pull.Dom三种方式) http://www.cnblogs.com/JerryWang1991/archive/2012/02/24/2365507.htm ...

  3. 微软BI 之SSIS 系列 - 数据仓库中实现 Slowly Changing Dimension 缓慢渐变维度的三种方式

    开篇介绍 关于 Slowly Changing Dimension 缓慢渐变维度的理论概念请参看 数据仓库系列 - 缓慢渐变维度 (Slowly Changing Dimension) 常见的三种类型 ...

  4. Android中webview跟JAVASCRIPT中的交互

    在android的应用程序中,可以直接调用webview中的javascript代码,而webview中的javascript代码,也可以去调用ANDROID应用程序(也就是JAVA部分的代码).下面 ...

  5. jQuery中通过JSONP来跨域获取数据的三种方式

    第一种方法是在ajax函数中设置dataType为'jsonp' $.ajax({ dataType: 'jsonp', url: 'http://www.a.com/user?id=123', su ...

  6. Android中Webview使用javascript调用事先定义好的Java函数

    1. 首先定义好一个类,专们用于给javascript调用 public class JavaScriptInterface { // share your news public void shar ...

  7. Android中webView和网页的交互

     Android中webView和网页的交互 Android中webView跟网页的交互式通过JavaScript进行的.具体步骤: 1.创建JavaScript,在点击的时候调用JavaScript ...

  8. Android中webView的基础使用(一)

    WebView是View的一个子类,可以让你在activity中显示网页. 可以在布局文件中写入WebView:比如下面这个写了一个填满整个屏幕的WebView: <?xml version=& ...

  9. Android 中Webview 自适应屏幕

    随笔 - 478  文章 - 3  评论 - 113 Android 中Webview 自适应屏幕   webview中右下角的缩放按钮能不能去掉 settings.setDisplayZoomCon ...

随机推荐

  1. UVA 6199 不定根最小树形图

    首先是最小树形图的介绍. 看这个博客.最小树形图 上面介绍的很详细了,我就讲一下这道题的题意. 首先给出一些二维点坐标,这些坐标之间构成一些有向图,根据题意,假设两个点a(x1 ,y1) ,b(x2 ...

  2. IO 流—>>>补充

    流操作规律: 示例:1. 源: 键盘录入 目的: 控制台 2.源:文件 目的:控制台 3.源: 键盘录入 目的: 文件 基本规律: 面对流对象很多,不知道用哪一个的时候: 通过两个明确来完成 1.明确 ...

  3. SOA体系结构基础培训教程-规范标准篇

    引子:本文是<SOA体系结构基础培训教程>第3章<SOA标准与规范>课件,版权所有,转载请注明出处. 随着SOA在业界的应用日益广泛,SOA的标准化问题也成为各界日益关注的焦点 ...

  4. 【转】Android应用开发allowBackup敏感信息泄露的一点反思

    转载:http://blog.csdn.net/yanbober/article/details/46417531 1 背景 其实这篇文章可能有些小题大作,但回过头想想还是很有必要的,有点阴沟里翻船的 ...

  5. 半斤八两(创业兴家版 打工仔心声'98 Remix)

    创业兴家打工仔 刻苦工作热诚日夜维系天天专心向上依足正轨 结力好比兄弟努力一生打工仔 相亲相爱朋情日夜传递彼此一家那用分高与低 要互相多鼓励 半斤八两 莫记往昔的创伤半斤八两 面对春光应插秧半斤八两 ...

  6. 闪回还原点(Flashback Restore Point)

    Flashback Restore Point(闪回还原点) 闪回还原点分两种,一种是Normal Restore Points(正常还原点),另一种是Guaranteed Restore Point ...

  7. netsh

    NetSH (Network Shell) 是windows系统本身提供的功能强大的网络配置命令行工具. 导出配置脚本:netsh -c interface ip dump > c:\inter ...

  8. Cocos2d-x中获取设备语言的方法

    1.cocos2dx获取设备语言的方法:CCApplication::sharedApplication()->getCurrentLanguage() 2.cocos2dx 2.1.4支持识别 ...

  9. C#中对于可变性的限制

    发现很少有集中讨论C#可变性限制的中文博文(要么就是一大段文字中夹杂很多凌乱的部分),所以写发篇博文,集中讨论,这些限制基本是基于安全考虑,亦或者根本难以实现而产生的. 注:本文不再解释什么是可变性, ...

  10. Oracle学习----集群因子(Clustering Factor)

    1.集群因子的算法: 通过dbms_rowid.rowid_block_number(rowid)找到记录对应的block 号.索引中记录了rowid,因此oracle 就可以根据索引中的rowid来 ...