标签归档:WebView挂马

我读书少,你不要骗我

2015-01-14 15:04:46 的屏幕截图

2015-01-14 15:06:36 的屏幕截图

这两天不知为何就冒出来这么一条新闻,Google具体宣布了什么我就不查了,但是感觉新闻报道的有点危言耸听和有失准确。以下单纯聊下漏洞问题。

在很久很久以前,Android系统WebView控件的addJavascriptInterface接口爆出漏洞,详情参见:WebView中接口隐患与手机挂马利用 。如果我没记错的话,当时国内应用甚至包括微信、360家产品等倒了一片,主流浏览器好像就只有UC幸免。

问题漏洞是CVE-2012-6636,API 17以下系统均躺枪,修复的方法是——升!级!系!统!!所以呢,一个比较简单的解决办法是,各家良心企业在自己的App中使用WebView控件的时候,如果是API 17以下则不要使用addJavascriptInterface接口。

这还没完,又陆续爆出了:CVE-2013-4710CVE-2014-1939CVE-2014-7224

这几个漏洞意思大概就是,虽然自己App不使用addJavascriptInterface了,但是系统的一些功能用到了addJavascriptInterface接口,大概有三个:searchBoxJavaBridge_ 、accessibility 、 accessibilityTraversal。所以,最保险的解决方案而是重载addJavascriptInterface为空方法,万一调用了这个接口也不会导致问题。

这样就万无一失了吗?太天真了,图样图森破!

查看源码会发现searchBoxJavaBridge_对象并不是通过调用addJavascriptInterface方法添加的,而是直接塞进去了mJavaScriptObjects的map中(调用addJavascriptInterface方法也是塞到这个map中):

2015-01-14 15:28:32 的屏幕截图

/* package */ static final String JS_INTERFACE_NAME = "searchBoxJavaBridge_";

2015-01-14 15:27:43 的屏幕截图

mSearchBox = new SearchBoxImpl(mWebViewCore, mCallbackProxy);
mJavaScriptObjects.put(SearchBoxImpl.JS_INTERFACE_NAME, mSearchBox);

所以,对于API17以下,使用WebView控件的时候,不光要记得重载addJavascriptInterface为空方法,还要主动移除searchBoxJavaBridge_。

如果有同学有疑问,addJavascriptInterface接口不能用了,那怎么做JS与Native的交互?哎,曲线救国一下吧:在WebViewClient.shouldOverrideUrlLoading()里面捕捉一下iFrame跳转吧……具体不再说了,资料都比较好查。

好啦,讲到这里差不多了,顺便贴一个比较简单的解决方案,继承WebView自定义控件,然后项目中一律使用自定义的WebViewEx控件。

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.webkit.WebView;

/**
 * 
 * 解决Android 4.2以下的WebView注入Javascript对象引发的安全漏洞
 * 
 * @author mengsifan
 * @date [2014年10月9日]
 */
public class WebViewEx extends WebView {

    public WebViewEx(Context context) {
        super(context);
        removeSearchBoxJavaBridgeInterface();
    }

    public WebViewEx(Context context, AttributeSet attrs) {
        super(context, attrs);
        removeSearchBoxJavaBridgeInterface();
    }

    public WebViewEx(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        removeSearchBoxJavaBridgeInterface();
    }

    @SuppressWarnings("deprecation")
    @SuppressLint("NewApi")
    public WebViewEx(Context context, AttributeSet attrs, int defStyle,
            boolean privateBrowsing) {
        super(context, attrs, defStyle, privateBrowsing);
        removeSearchBoxJavaBridgeInterface();
    }

    @SuppressLint("NewApi")
    private void removeSearchBoxJavaBridgeInterface() {
        if (Build.VERSION.SDK_INT >= 11 && Build.VERSION.SDK_INT < 17) {
            removeJavascriptInterface("searchBoxJavaBridge_");
        }
    }

    @Override
    public void addJavascriptInterface(Object object, String name) {
        // API 17以下版本暂时不允许使用addJavascriptInterface方法,防止系统调用造成注入漏洞。
        if (Build.VERSION.SDK_INT >= 17) {
            super.addJavascriptInterface(object, name);
        }
    }
}