Webview与js交互漏洞及解决方法(有注释代码)

本文探讨了Android WebView存在的安全漏洞,该漏洞允许JS遍历并调用Native方法。虽然在Android 4.2后已修复,但为了兼容性和安全性,作者建议避免使用`addJavascriptInterface`。提出了利用`prompt`方法作为安全通道,通过前端调用prompt传递信息,原生代码拦截处理,实现安全的JS与Native交互。文章提供了代码实现和GitHub源码链接,以展示这种方法的实际应用。
摘要由CSDN通过智能技术生成

前两天去Tencent面试,被面试官问到这个问题,答得不是很好,于是回来总结一下,并提供了解决方法与大家分享。

在Android中,netive与js交互已经不是什么新鲜事。大多数人都知道WebView存在一个漏洞,大致是因为js可以通过webview的window对象获得Class然后通过遍历所有的方法,找到runtime方法,边,虽然该漏洞已经在Android 4.2上修复了,即使用@JavascriptInterface代替addJavascriptInterface,但是由于兼容性和安全性问题,基本上我们不会再利用Android系统为我们提供的addJavascriptInterface方法或者@JavascriptInterface注解来实现,所以我们只能另辟蹊径,去寻找既安全,又能实现兼容Android各个版本的方案。

我们发现当setWebChromeClient之后,前端调用的一些js方法如:alert、Prompt、confirm等方法都会走你自定义的WebChromeClient类中相对应的重写的方法,由于alert、confirm使用频率较高,我们不建议处理,而prompt使用频率就少多了,甚至基本没使用,于是思路来了:我们可以让前端调用prompt这个方法,传过来一些信息,然后原生拦截prompt方法,获取这些信息,然后确定需要调用的jsbridge。

代码实现:

首先看一下目录结构:
这里写图片描述

前端部分

1、在页面加载时先定义好一些方法,包括生成一段前端与原生自己定义好的内容格式(URI)、调用prompt的方法;

//JSBridge.js
//定义的URI内容格式如下:
//JSBridge://WindowJSBridge:821021544/toast?{"msg":"Hello JSBridge"}
//JSBridge:固定标识,两端统一即可;
//WindowJSBridge:要调用原生的bridge类名;
//821021544:存储在前端callback数组中的index,代表是哪个jsbridge请求的callback;
//toast:要调用的原生方法名;
//{"msg":"Hello JSBridge"}:携带给原生的参数;
(function (win) {
   
    var hasOwnProperty = Object.prototype.hasOwnProperty;
    var JSBridge = win.JSBridge || (win.JSBridge = {});
    var JSBRIDGE_PROTOCOL = 'JSBridge';
    var Inner = {
        callbacks: {},
        call: function (obj, method, params, callback) {
   
            console.log(obj+" "+method+" "+params+" "+callback);
            var port = Util.getPort();
            console.log(port);
            this.callbacks[port] = callback;
            var uri=Util.getUri(obj,method,params,port);
            console.log(uri);
            window.prompt(uri, "");
        },
        onFinish: function (port, jsonObj){
   
            var callback = this.callbacks[port];
            callback && callback(jsonObj);
            delete this.callbacks[port];
        },
    };
    var Util = {
        getPort: function () {
   
            return Math.floor(Math.random() * (1 << 30));
        },
        getUri:function(obj, method, params, port){
   
            params = this.getParam(params);
            var uri = JSBRIDGE_PROTOCOL + '://' + obj + ':' + port + '/' + method + '?' + params;
            return uri;
        },
        getParam:function(obj){
   
            if (obj && typeof obj === 'object') {
                return JSON.stringify(obj);
            } else {
                return obj || '';
            }
        }
    };
    for (var key in Inner) {
        if (!hasOwnProperty.call(JSBridge, key)) {
            JSBridge[key] = Inner[key];
        }
    }
})(window);

前端页面主要是通过点击button使用在上面js文件中定义好的方法调用原生方法。

<!DOCTYPE HTML , 前端页面>
<html>
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值