Android WebView安全方面的一些坑
公司一款app有将近两年没有更新了,虽然用户量不大,但是因为与第三方有合作,出现问题时需要进行维护;没想到最近第三方对他们所有的软件进行了网络安全扫描,这款Android app也未能幸免...
因为app是13年左右开发的,维护也只是到16、17年左右就终止了,所以,扫描出不少漏洞;因为是采用了webview+html混合开发,因此,需要解决一些webview相关的问题:
一、webview隐藏接口问题(任意命令执行漏洞)
android webview组件包含3个隐藏的系统接口:searchBoxJavaBridge_, accessibilityTraversal以及accessibility,恶意程序可以通过反射机制利用它们实现远程代码执行;该问题在Android4.4以下版本出现。
于是,在Android3.0到4.4之间的版本,我们通过移除这些隐藏接口,来解决该问题:
1 2 3 4 5 6 7 8 9 |
<span class="hljs-comment">// 19 4.4 Build.VERSION.KITKAT</span> <span class="hljs-comment">// 11 3.0 Build.VERSION_CODES.HONEYCOMB</span> <span class="hljs-keyword">if</span>(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB && Build.VERSION.SDK_INT < <span class="hljs-number">19</span> && webView != <span class="hljs-keyword">null</span>) { webView.removeJavascriptInterface(<span class="hljs-string">"searchBoxJavaBridge_"</span>); webView.removeJavascriptInterface(<span class="hljs-string">"accessibility"</span>); webView.removeJavascriptInterface(<span class="hljs-string">"accessibilityTraversal"</span>); } |
二、addJavascriptInterface任何命令执行漏洞
在webview中使用js与html进行交互是一个不错的方式,但是,在Android4.2(16,包含4.2)及以下版本中,如果使用addJavascriptInterface,则会存在被注入js接口的漏洞;在4.2之后,由于Google增加了@JavascriptInterface,该漏洞得以解决。
解决该问题,最彻底的方式是在4.2以下放弃使用addJavascriptInterface,采用onJsPrompt或其它方法替换。或者使用一些方案来降低该漏洞导致的风险:如使用https并进行证书校验,如果是http则进行页面完整性校验,如上面所述移除隐藏接口等。
1 2 3 4 5 6 |
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">onJsPrompt</span><span class="hljs-params">(WebView view, String url, String message,String defaultValue, JsPromptResult result)</span> </span>{ result.confirm(CGJSBridge.callJava(view, message)); Toast.makeText(view.getContext(),<span class="hljs-string">"message="</span>+message,Toast.LENGTH_LONG).show(); <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>; } |
三、绕过证书校验漏洞
webviewClient中有onReceivedError方法,当出现证书校验错误时,我们可以在该方法中使用handler.proceed()来忽略证书校验继续加载网页,或者使用默认的handler.cancel()来终端加载。
因为我们使用了handler.proceed(),由此产生了该“绕过证书校验漏洞”。
如果确定所有页面都能满足证书校验,则不必要使用handler.proceed()
1 2 3 4 5 6 7 |
<span class="hljs-meta">@SuppressLint</span>(<span class="hljs-string">"NewApi"</span>) <span class="hljs-meta">@Override</span> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onReceivedSslError</span><span class="hljs-params">(WebView view, SslErrorHandler handler, SslError error)</span> </span>{ <span class="hljs-comment">//handler.proceed();// 接受证书</span> <span class="hljs-keyword">super</span>.onReceivedSslError(view, handler, error); } |
四、allowFileAccess导致的File域同源策略绕过漏洞
如果webview.getSettings().setAllowFileAccess(boolean)设置为true,则会面临该问题;该漏洞是通过WebView对Javascript的延时执行和html文件替换产生的。
解决方案是禁止WebView页面打开本地文件,即
1 2 |
<span class="hljs-selector-tag">webview</span><span class="hljs-selector-class">.getSettings</span>()<span class="hljs-selector-class">.setAllowFileAccess</span>(<span class="hljs-selector-tag">false</span>); |
或者更直接的禁止使用JavaScript
1 2 |
<span class="hljs-selector-tag">webview</span><span class="hljs-selector-class">.getSettings</span>()<span class="hljs-selector-class">.setJavaScriptEnabled</span>(<span class="hljs-selector-tag">false</span>); |
由于业务上的原因,这个解决方案其实并不怎么理想,如果有更好的解决方案,欢迎指教!
原文:简书ThinkinLiu 博客: IT老五
这是都是关于WebView网络安全方面的问题,其他非安全漏洞方面的坑这里就不说了。
做开发越久,越觉得自己不会的太多;如果文中有错误之处,麻烦指出,多谢!