WebView中addJavascriptInterface接口的隐患解决方案

本文介绍如何使用WebView展示网页,并实现JavaScript与Java代码之间的交互。同时探讨了WebView的安全隐患及应对措施,包括过滤本地文件访问、限制加载未知站点、移除默认JavaScript接口等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们很多时候要使用WebView来展示一个网页,现在很多应用为了做到服务端可控,很多结果页都是网页的,而不是本地实现,这样做有很多好处,比如界面的改变不需要重新发布新版本,直接在Server端修改就行了。用网页来展示界面,通常情况下都或多或少都与Java代码有交互,比如点击网页上面的一个按钮,我们需要知道这个按钮点击事件,或者我们要调用某个方法,让页面执行某种动作,为了实现这些交互,我们通常都是使用JS来实现,而WebView已经提供了这样的方法,具体用法如下:
[java]  view plain  copy
  1. mWebView.getSettings().setJavaScriptEnabled(true);  
  2. mWebView.addJavascriptInterface(new JSInterface(), "jsInterface");  

我们向WebView注册一个名叫“jsInterface”的对象,然后在JS中可以访问到jsInterface这个对象,就可以调用这个对象的一些方法,最终可以调用到Java代码中,从而实现了JS与Java代码的交互。


但是用addJavascriptInterface可能导致不安全,因为JS可能包含恶意代码。


假如我们自己没有添加addJavascriptInterface,甚至默认为false呢。?还是有漏洞!因为在低于API17的WebView上默认添加"searchBoxJavaBridge_"到mJavaScriptObjects中。


        这样就有可能通过用户信任的客户端获取SD卡的数据。

        解决方法有几点:

        1. 过滤本地文件的访问: 

[java]  view plain  copy
  1. if (!url.startsWith("file://")) {  
  2.         // to do.  
  3. }  

        2. 过滤未知网站(可以非本站点的都不允许加载)

        3. 删除默认添加的"searchBoxJavaBridge_"

[java]  view plain  copy
  1. // in WebView setting:  
  2.         if (Build.VERSION.SDK_INT > 10&&Build.VERSION.SDK_INT < 17) {  
  3.             fixWebView();  
  4.         }  
  5.   
  6. // fixWebView like this:  
  7.     @TargetApi(11)  
  8.     private void fixWebView() {  
  9.             //        http://50.56.33.56/blog/?p=314  
  10.             //        http://drops.wooyun.org/papers/548  
  11.             // We hadn't use addJavascriptInterface, but WebView add "searchBoxJavaBridge_" to mJavaScriptObjects below API 17 by default:  
  12.             // mJavaScriptObjects.put(SearchBoxImpl.JS_INTERFACE_NAME, mSearchBox);  
  13.             mWebView.removeJavascriptInterface("searchBoxJavaBridge_");  
  14.     }  


    4. (prompt()$onJsPrompt()/confirm()$onConfirm()/alert()$onAlert()):

继承该WebChromeClient重写以上三个
方法其中一个的具体实现
class HarlanWebChromeClient extends WebChromeClient {

        /*此处覆盖的是javascript中的alert方法。
         *当网页需要弹出alert窗口时,会执行onJsAlert中的方法
         * 网页自身的alert方法不会被调用。
         */
        @Override
        public boolean onJsAlert(WebView view, String url, String message,
                                 JsResult result) {
            show("onJsAlert");
            result.confirm();
            return true;
        }

        /*此处覆盖的是javascript中的confirm方法。
         *当网页需要弹出confirm窗口时,会执行onJsConfirm中的方法
         * 网页自身的confirm方法不会被调用。
         */
        @Override
        public boolean onJsConfirm(WebView view, String url,
                                   String message, JsResult result) {
            show("onJsConfirm");
            result.confirm();
            return true;
        }

        /*此处覆盖的是javascript中的confirm方法。
         *当网页需要弹出confirm窗口时,会执行onJsConfirm中的方法
         * 网页自身的confirm方法不会被调用。
         */
        @Override
        public boolean onJsPrompt(WebView view, String url,
                                  String message, String defaultValue,
                                  JsPromptResult result) {
            show("onJsPrompt....");
            result.confirm();
            return true;
        }

然后给webView设置该重写的类

//设置ChromeClient
mWebView.setWebChromeClient(new HarlanWebChromeClient());
相应的在JS中的具体实现代码如下
function cfm() {
            confirm("")
        }

        function pmt() {
           prompt("","");
        }

        function onAlert()
        {
            alert("这是网页中的alert方法,如果重写了mWebView的onAlert方法,该方法不会执行");
        }
触发页面中的js函数,例如:
<p><input type="button" onclick="cfm()" value="Confirm"/></p>
<p><input type="button" onclick="pmt()" value="Prompt"/></p>
<p><input type="button" onclick="onAlert()" value="Alert"/>

实现原理就是在页面中触发的方法被webView中设置的WebChromeClient给拦截了,从而执行了WebChromeClient中重写的onXxx()方法, 没有执行页面中相应的onXxx()方法,这是方式相对简单,而且安全。

参考链接: https://github.com/Sunzxyong/RainbowBridge

   http://blog.youkuaiyun.com/owillll/article/details/20996139

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值