Android APP Webview安全风险漫谈(翻译)

Android APP Webview安全漫谈

刚好看到checkmarx的博客有说到Android APP的webview的常见的安全问题,2017年底的克隆攻击火了一把。T和A的安全团队相互对核心APP进行了友谊赛,大厂的安全实力可见一斑。

ROUND one

第一部分
WebView这个特性给Android APP给了很多方便的功能,可以加载很多资源。但是也带了极大的安全风险。
前面介绍了很多app的开发模式:原生,混合,web based。

由于WebView允许加载web的资源,也可以调用原生函数的资源,这就是为什么还有那么多公司使用他的原因。

在Android 4.3 (Jelly Bean)之前,WebView是基于WebKit的,被发现一些安全问题。迫使一些大厂(三星和HTC等)把默认的WebView换成更先进的版本,或者Chromium,因为他们对HTML5支持更好。

现在Android 5.0 (Lollipop)开始,APP的WebView版本都是可以和手机系统分开来升级。

Loading Clear-Text Content(LCTC)

这个就是明文传输,由于Android APP不会限定强制使用HTTPS(iOS app store app会的),这个会造成中间人攻击。
下面是漏洞代码demo(本来想直接贴图片的链接,假装自己很勤奋,我就手动敲一下下)

1
2
3
4
5
6
7
8
9
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

WebView mywebview = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebview.getSettings();
mywebview.addJavascriptInterface(new WebAppInterface(this), "Android");
mywebview.loadUrl("http://10.0.0.2/login.php");
}

SSL Error Handling

就是没有做好证书检验,没有做好证书校验(SSL Pin)也会可以被中间人攻击。

Enabling JavaScript

允许加载javascript,WebView默认是禁止加载js的。
检测的代码有

1
2
<h6>TEST</h6>
<script>document.write(Android.showPlayerName());</script>

修复的代码demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class mainActivity extends AppCompatActivity{

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

WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
WebSettings.setJavaScriptEnable(false);
mywebview.addJavascriptInterface(new WebAppInterface(this), "Android");
mywebview.loadUrl("http://10.0.0.2/login.php");
}

}

Accessing Local Resources

Webview默认是可以加载本地资源的,可以导致目录穿越,任意文件读取。
下面是一些WebView的权限

  • setAllowContentAccess,默认是true的,允许访问content providers组件。
  • setAllowFileAccess,默认是true的,使用”file://“读取本地文件
  • setAllowFileAccessFromFileURLs,在API(Jelly Bean)之后都是false,之前都是true。允许加载本地的html,js加载。
  • setAllowUniversalAccessFromFileURLs,在API(Jelly Bean)之后都是false,之前都是true。允许加载任意域下面的资源。

可见使用file协议是可以读取本地文件的。
下面是漏洞代码demo

1
myWebView.loadUrl("file:///androif_asset/www/players" + showPlayerName());

由于直接拼接了showPlayerName,如果没有做过滤,payload

1
../../../storage/emulated/0/Pictures/pic001.jpg

可以读取本地文件

Using JavascriptInterfaces

JavascriptInterfaces可以执行java的方法。

API 17 (Jelly Bean – Android 4.2)之前,CVE-2012-6636,代码执行漏洞。

API 17之后,只有@JavascriptInterface 注解的方法才会被javascript调用执行。

Validating Content from Third-Parties

就是同源策略。不要加载非本域的资源,避免app被攻击。我现在看到很多app的做法就是如果不是本域的话,那么直接调用系统浏览器。
修复代码demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

WebView mywebview = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebview.getSettings();
mywebview.addJavascriptInterface(new WebAppInterface(this), "Android");
mywebview.loadUrl("http://10.0.0.2/login.php");
}

private class MyWebViewClient extends WebViewClient{
@override
public boolean shouldOverideurlLoading(WebView webview, String url){
if (!url.startsWith("https://www.checkmarx.com"))
url = "https://www.checkmarx.com/contact-us";
webView.loadurl(url);
return true;
}
}

这里的demo有个问题。可以用https://www.checkmarx.com@baidu.com绕过,额额额额。

ROUND two

第二部分
这部分没什么好说的。也就是说到XSS怎么利用

ROUND Tree

第三部分
这里说到怎么利用webview的漏洞进行传输输出。主要是由于如果可以被javascript调用的方法,实现不好,那么都是存在风险的。
这一部分就不展开了。有点高级,因为还说到用手机的闪光等来传输数据的,就是一闪一闪,亮星星。

参考链接