WebView之与 JavaScript 交互,Js 注入漏洞,,JSBridge

                    WebView之与 JavaScript 交互Js 注入漏洞,,JSBridge

1.与 JavaScript 交互

(1)使用系统方法 addJavascriptInterface 注入 java 对象来实现。

(2)利用 WebViewClient 中 shouldOverrideUrlLoading (WebView view, String url) 接口,拦截操作。这个就是很多公司在用的 scheme 方式,通过制定url协议,双方各自解析,使用iframe来调用native代码,实现互通。

(3)利用 WebChromeClient 中的 onJsAlert、onJsConfirm、onJsPrompt 提示接口,同样也是拦截操作。

//开启Js可用
mWebView.getSettings().setJavaScriptEnabled(true);

// 创建要注入的 Java 类
public class NativeInterface {

    private Context mContext;

    public NativeInterface(Context context) {
        mContext = context;
    }

    @JavascriptInterface
    public void hello() {
        Toast.makeText(mContext, "hello", Toast.LENGTH_SHORT).show();
    }

    @JavascriptInterface
    public void hello(String params) {
        Toast.makeText(mContext, params, Toast.LENGTH_SHORT).show();
    }

    @JavascriptInterface
    public String getAndroid() {
        Toast.makeText(mContext, "getAndroid", Toast.LENGTH_SHORT).show();
        return "Android data";
    }

}

// WebView 注入即可
mWebView.addJavascriptInterface(new NativeInterface(this), "AndroidNative");

//Js编写
<script>
    function callHello(){
        AndroidNative.hello();
    }

    function callHello1(){
        AndroidNative.hello('hello Android');
    }

    function callAndroid(){
        var temp = AndroidNative.getAndroid();
        console.log(temp);
        alert(temp);
    }  

</script>

Js 注入漏洞

虽然可以通过注入方式来实现 WebView 和 JS 交互,但是实现功能的同时也带了安全问题,通过注入的 Java 类作为桥梁,JS 就可以利用这个漏洞。

如何解决漏洞

1、Android 4.2 以下不要在使用 JavascriptInterface方式,4.2 以上需要添加注解 @JavascriptInterface 才能调用。(这部分和JsBrige 有关,更详细的内容后面会介绍)

2、在创建 WebView 时,使用 removeJavascriptInterface 方法将系统注入的 searchBoxJavaBridge_ 对象删除。

3、当系统辅助功能服务被开启时,在 Android 4.4 以下的系统中,由系统提供的 WebView 组件都默认导出 ”accessibility” 和 ”accessibilityTraversal” 这两个接口,这两个接口同样存在远程任意代码执行的威胁,同样的需要通过 removeJavascriptInterface 方法将这两个对象删除。

       super.removeJavascriptInterface("searchBoxJavaBridge_");
       super.removeJavascriptInterface("accessibility");
       super.removeJavascriptInterface("accessibilityTraversal");

JSBridge

相信很多都或多或少的了解 JsBridge,不管是 iOS 平台还是 Android平台,特别是 Hybrid 应用,肯定是要用的 JsBridge 这个机制来建立 Native 和 Web 端的通信。

JsBridge 介绍:

JSBridge 我们可以比喻成一座桥或者一根管道,一端是 Web一端是 Native。我们搭建这个通道的目的就是让 Native 和 Web 之间互相调用更为方便统一和简洁。
JSBridge 做得好的一个典型就是微信,微信给开发者提供了 JSSDK,该SDK中暴露了很多微信native层的方法,比如支付,定位等。使用起来非常方便。

JsBridge 原理:

前面我们分析了 WebView 如何于 JavaScript 交互的,JSBridge 就是在这些基础之上做扩展使它支持更复杂的功能,三种形式两种原理分析如下:

1、使用 addJavascriptInterface

原理:这是Android提供的Js与Native通信的官方解决方案,将 java 对象注入到 Js 中直接作为window的某一变量来使用。

2、WebViewClient 中 shouldOverrideUrlLoading (WebView view, String url)。

利用 scheme iframe 机制,只要有iframe 加载,shouldOverrideUrlLoading 方法就会有回调。可以构造一个特殊格式的url,使用shouldOverrideUrlLoading 方法拦截url,根据解析url来之行native方法逻辑。

3、利用 WebChromeClient 中的 onJsAlert、onJsConfirm、onJsPrompt 提示接口,同样也是拦截操作。

native 调 js:

1、WebView.callHandler('handlerName','{}',callBack);
2、doSend 中组装 要传输的 Message 对象,并设置setCallbackId(生成唯一的id是为了方便在js回调回来的时候在android端查找对于的 callback)
3、dispatchMessage javascript:WebViewJavascriptBridge._handleMessageFromNative(message);方法 message 为上一步的Message 对象对应的 Json 数据。
4、在 Js _dispatchMessageFromNative 函数中,根据 messageJSON json 数据中的字段 handlerName 找到对对应的 handler 方法执行。
handler = messageHandlers[message.handlerName];handler 这个就是在 html 中 registerHandler 注册的回调function(data, responseCallback)函数
5、之后执行 html 中 responseCallback(responseData); 会触发 WebViewJavascriptBridge.js 文件中的 _doSend函数,_doSend 通过 messagingIframe.src 形式传给 android端,shouldOverrideUrlLoading 接受,并拦截内容处理。
6、第一次:拦截执行到 webView.flushMessageQueue()方法,并调用 responseCallbacks.put(jsUrl,returnCallback);,同时调用 javascript:WebViewJavascriptBridge._fetchQueue(); 来查询消息的返回值,并执行一次messagingIframe.src。
7、第二次:拦截执行到 webView.handlerReturnData() 方法,并调用上一步注册的 CallBackFunction.onCallBack,然后根据responseId 即 android 传过来的 message.callbackId,找到 使用者注册的 CallBackFunction 回调。

Js -> android:

1、window.WebViewJavascriptBridge.callHandler
2、执行 Js 函数 _doSend() 触发 messagingIframe.src
3、android 端拦截,shouldOverrideUrlLoading
4、第一次:拦截执行到 webView.flushMessageQueue()方法,并调用 responseCallbacks.put(jsUrl,returnCallback);,同时调用 javascript:WebViewJavascriptBridge._fetchQueue(); 来查询消息的返回值,并执行一次messagingIframe.src。
5、第二次:拦截执行到 webView.handlerReturnData() 方法,并调用上一步注册的 CallBackFunction.onCallBack -> responseId 为空 -> handler.handler(m.getData(), responseFunction)-> 外部回调( function.onCallBack("native submitFromWeb 方法, 返回 data");)-> queueMessage -> dispatchMessage ->loadUrl(javascriptCommand) -> 回调结束



 

猜你喜欢

转载自blog.csdn.net/weixin_42248302/article/details/86654978
今日推荐