Android中的WebView组件安全

0x01 WebView组件远程代码执行漏洞

漏洞描述
CVE-2012-6636
Android API level 16以及之前的版本存在远程代码执行安全漏洞,该漏洞源于程序没有正确使用WebView.addJavascriptInterface方法,远程攻击者可通过使用Java Reflection API利用该漏洞执行任意Java对象的方法,简单的说就是通过addJavascriptInterface给WebView加入一个JavaScript桥接接口,JavaScript通过调用这个接口可以直接操作本地的JAVA接口。


CVE-2014-1939
java/android/webkit/BrowserFrame.java 使用addJavascriptInterface API并创建了SearchBoxImpl类的对象。攻击者可通过访问searchBoxJavaBridge_接口利用该漏洞执行任意Java代码。
Google Android <= 4.3.1 受到此漏洞的影响


CVE-2014-7224
香港理工大学的研究人员发现当系统辅助功能中的任意一项服务被开启后,所有由系统提供的WebView都会被加入两个JS objects,分别为是accessibility和accessibilityTraversal。恶意攻击者就可以使用accessibility和accessibilityTraversal这两个Java Bridge来执行远程攻击代码.由于系统辅助功能
非默认开启且很少使用,所以利用条件还是比较苛刻。
Google Android < 4.4 受到此漏洞的影响。

漏洞原理和代码

activity中webview漏洞代码,这段代码虽然自身没有实现java和js交互接口,但是会调用系统默认的“searchBoxJavaBridge_”接口。

package com.pc.webview;

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        WebView webview = (WebView)findViewById(R.id.webView);
        webview.getSettings().setJavaScriptEnabled(true);
        //webview.addJavascriptInterface(new MyInterface(), "myobj"); 自身实现的js和java交互接口myobj
        webview.loadUrl("http://192.168.xx.xxx/webview.html");
        
    }

检测页面

webview.html为漏洞检测代码,代码如下

<!DOCTYPE html> 
<html> 
<head> 
<meta charset="UTF-8" /> 
<title>WebView 漏洞检测</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"> 
</head>
<body>
<p>
<b>如果当前 app 存在漏洞,将会在页面中输出存在漏洞的接口方便程序员做出修改:</b>
</p> 
<script type="text/javascript"> 
function check() 
{ 
  for (var obj in window) 
   { 
      try {
            if ("getClass" in window[obj]) { 
                        try{ 
                             window[obj].getClass();
                             document.write('<span style="color:red">'+obj+'</span>');                              
                             document.write('<br />');
                        }catch(e){
                        } 
                      } 
                 } catch(e) {
                 }
              } 
} check();
</script>
</body> 
</html>

检测结果

由于我们测试的android系统版本是android4.4.2, 所以检测时不存在漏洞。


漏洞防御
1. API Level>=17的Android系统
      出于安全考虑,为了防止Java层的函数被随便调用,Google在4.2版本之后,规定允许被调用的函数必须以@JavascriptInterface进行注解,所以如果某应用依赖的API Level为17或者以上,就不会受该问题的影响(注:Android 4.2中API Level小于17的应用也会受影响)。按照Google官方文档使用示例:
        class JsObject {
            @JavascriptInterface
            public String toString() { return "injectedObject"; }
        }
        webView.addJavascriptInterface(new JsObject(), "injectedObject");
        webView.loadData("", "text/html", null);
        webView.loadUrl("javascript:alert(injectedObject.toString())");


对于API Level低于17的Android系统,建议不要使用addJavascriptInterface接口,以免带来不必要的安全隐患。

建议利用WebViewClient接口回调方法拦截url方式或者利用WebChromeClient回调接口的三个方法拦截消息方式进行js和java本地代码的交互。

参考链接:  http://blog.csdn.net/jiangwei0910410003/article/details/52687530



3.移除Android系统内部的默认内置接口,调用removeJavascriptInterface(“searchBoxJavaBridge_”);方法移除searchBoxJavaBridge_。调用removeJavascriptInterface("accessibility") 和removeJavascriptInterface("accessibilityTraversal") 方法移除这两个默认接口。


0x02 WebView明文存储密码风险

在我们使用WebView的过程中,如果有输入账号和密码的情况,系统会弹出提示询问是否保存密码,如果用户选择了是,那么这个密码会以明文的形式存储到databases/webview.db中。

漏洞代码

webview.getSettings().setSavePassword(true); //如果setSavePassword值为true或者没有设置setSavaPassword这个参数。
webview.loadUrl("http://www.xxx.com");


漏洞防御
使用了密码登录相关功能时,把setSavePassword值设为false即可。
webview.getSettings().setSavePassword(false)


0x03 WebView组件系统隐藏接口漏洞

隐藏的接口就是searchBoxJavaBridge_、 accessibility 和accessibilityTraversal接口。详情参考webview命令执行漏洞部分。


0x04 WebView File域同源策略绕过

什么是同源策略同源策略
同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。
所谓同源是指,域名,协议,端口相同。


File URI跨域的原理

Android 4.1版本一下中,如果WebView没有禁止使用file域,并且WebView打开了对JavaScript的支持,我们就能够使用file域进行攻击。在File域下,能够执行任意的JavaScript代码,同源策略跨域访问能够对私有目录文件进行访问。APP中如果使用的WebView组件未对file协议头形式的URL做限制,会导致隐私信息泄露问题。


Android 4.1到Android 4.4版本中,为了安全使用WebView, AllowUniversalAccessFromFileURLs和AllowFileAccessFromFileURLs都应该设置为禁止,如果允许File Url
执行javascript,我们可以通过符号链接(即软链接,像我们常看到的快捷方式一样)的攻击方式达到跨域的目的。


File URI跨域的java代码

public class MainActivity extends ActionBarActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);

                WebView webview = (WebView)findViewById(R.id.webView);
                webview.getSettings().setAllowFileAccess(true);                    
                webview.getSettings().setJavaScriptEnabled(true);                   
                webview.getSettings().setAllowFileAccessFromFileURLs(true);       
                webview.getSettings().setAllowUniversalAccessFromFileURLs(true); 
        
                Intent i = getIntent();
                String url = i.getData().toString();
                webview.loadUrl(url);

	}

}

webview.getSettings().setAllowFileAccess(true);

setAllowFileAccess设置的是否允许Webview使用File协议,默认情况是允许的,如果设置为false的,则不能利用file协议访问本地文件。   
webview.getSettings().setJavaScriptEnabled(true);             

setJavaScriptEnabled设置的是否允许Webview使用javaScript,默认是不允许的,很多浏览器由于需要执行js会设置这个值为true,所以

加载url时,最好判断是http或者https允许执行js,如果是file就禁止掉,这是比较安全的方式。


webview.getSettings().setAllowFileAccessFromFileURLs(true); 

setAllowFileAccessFromFileURLs设置是否允许通过file url加载的Javascript读取其他的本地文件,在android4.1版本

后默认关闭。
webview.getSettings().setAllowUniversalAccessFromFileURLs(true);

setAllowUniversalAccessFromFileURLs是否允许通过file url加载的Javascript可以访问其他的源,包括其他的文件和http,https等其他的源

在android4.1版本过后也是关闭的。


测试的命令和代码

如果开启了javascript且file协议没有禁止,可以用一下名字检测

检测方式 adb命令对组件进行检查

adb shell am start -n com.pc.webview/.MainActivity -d file:///system/etc/hosts


使用drozer进行检查
dz> run app.activity.start --component com.pc.webview com.pc.webview.MainActivity --action
 android.intent.action.VIEW --data-uri file:///data/data/com.pc.webview/databases/webview.db

如果开启了javascript且没有禁止file协议,而且允许javascript读取本地文件和加载其他http或https的源,建议使用如下代码进行测试。

检测方式 adb命令对组件进行检查

adb shell am start -n com.pc.webview/.MainActivity -d file:///android_asset/webview_test.html


使用drozer进行检查
dz> run app.activity.start --component com.pc.webview com.pc.webview.MainActivity --action
 android.intent.action.VIEW --data-uri file:///android_asset/webview_test.html

webview_test.html测试代码

</pre><pre name="code" class="html"><html>
<head>
</head>
<title>File URI</title> 
<script>
function loadXMLDoc()
{
    var arm = "file:///system/etc/host";  //允许javascript读取本地文件
    //var arm = "http://www.xxx.com/";    //允许javascript加载其他的源
    var xmlhttp;
    if (window.XMLHttpRequest)
    {
        xmlhttp=new XMLHttpRequest();
    }
    xmlhttp.onreadystatechange=function()
    {
        //alert("status is"+xmlhttp.status);
        if (xmlhttp.readyState==4)
        {
            alert(xmlhttp.responseText);
            console.log(xmlhttp.responseText);
        }
    }
    xmlhttp.open("GET",arm);
    xmlhttp.send(null);
}
loadXMLDoc();
</script>    
<body>
</body>
</html> 

android4.1到android4.4受影响的版本的验证参考如下链接。

原理是利用js延时并建立软链接的方式进行的跨域。

参考链点如下:https://jaq.alibaba.com/community/art/show?spm=a313e.7916648.0.0.zhYJ05&articleid=62


File跨域安全防御

1.如果组件为私有组件,建议设置exported属性为false的。

2如果组件为公有组件,如果在webview中不需要使用file协议,建议禁止file协议。

3.对于需要使用file协议的应用,建议file协议禁止调用javascript。


0x05 WebView外部URl可控

漏洞解释

 Activity可被其它应用程序掉用并加载一个外部传入的链接,可被用来进行钓鱼攻击,或者进一步进行漏洞利用。

漏洞防御

不需要导出的组件不要导出


0x06 WebView绕过证书校验漏洞

漏洞描述

Android WebView组件加载SSL书认证发生错误时,会调用WebViewClient类的onReceivedSslError方法,如果该方法实现调用了handler.proceed()来忽略该证书错误,则会受到中间人攻击的威胁,可能导致隐私泄露。


漏洞代码

如果使用的handlercancel()方法就好 出现安全问题。

package com.pc.webview;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.webkit.SslErrorHandler;
import android.webkit.WebView;
import android.webkit.WebViewClient;


public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        WebView mwebview = (WebView)findViewById(R.id.webview);
        mwebview.loadUrl("https://github.com/");
        mwebview.setWebViewClient(new WebViewClient(){
        	
        	public void onReceivedSslError(WebView view,SslErrorHandler handler,SslError error){
        		handler.proceed(); //接受所有的ssl证书,忽略ssl产生的错误
        		//handler.cancel(); 默许的处理方法,WebView停止加载并显示空白页
        		//handleMessage(Message msg); 其他处理
        	}
        	public boolean shouldOverriderUrlLoading(WebView view,String url){
        		view.loadUrl(url);
        		return true;
        	}
        });
    }
}


漏洞防御

禁止调用handler.proceed()方法,使用默认的handler.cancel()函数处理https错误。



参考链接
webview执行命令原理
http://blog.nsfocus.net/android-webview-remote-code-execution-vulnerability-analysis/

java的放射机制
http://www.jb51.net/article/36473.htm
http://blog.csdn.net/kaiwii/article/details/7405761

WebView远程代码执行漏洞浅析
https://jaq.alibaba.com/community/art/show?spm=a313e.7975615.40002100.2.drjYfR&articleid=48

实现js和java相互调用的非android官方代码,可以防御代码执行漏洞
http://blog.csdn.net/theone10211024/article/details/49057039

android中js和java交互详解
http://blog.csdn.net/faithmy509/article/details/42078233

@JavascriptInterface注解作用
http://blog.csdn.net/zzf112/article/details/19546859


android File跨域问题
http://www.tuicool.com/articles/Q36ZfuF
https://jaq.alibaba.com/community/art/show?spm=a313e.7916648.0.0.zhYJ05&articleid=62
http://blogs.360.cn/360mobile/2014/09/22/webview跨源攻击分析/

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值