最近需要检测一个网页的源码。AndroidWebview中没有直接获取网页源码的接口。传统的addJavascriptInterface方法存在安全隐患,所以我们研究了Java和Javascript的安全性。相互影响。AndroidWebview漏洞AndroidWebview有两个非常知名的漏洞:最近曝光的UXSS漏洞可以绕过同源策略,获取任意网页的cookies等信息。这个问题在Android4.4及以下版本存在,基本没有解决办法。只能重新编译。浏览器内核解决了。详情请参考近期发生的手机安全事件。感兴趣的可以观看@RAyH4c劫持微博和QQ空间的视频。著名的任意命令执行漏洞,通过addJavascriptInterface方法,Js可以调用Java对象的方法,通过反射机制,Js可以直接获取Runtime执行任意命令。对于Android4.2及以上版本,可以声明@JavascriptInterface来保证安全。4.2以下,不能再调用addJavascriptInterface,需要另辟蹊径。Java与Javascript的安全交互首先要说明几点:1、Java很容易调用AndroidWebview中的Js方法。loadUrl("javascript:isOk()")可以调用Js方法isOk,但是不能直接获取Js方法的返回结果。classJsObject{@JavascriptInterfacepublicStringtoString(){return"injectedObject";}}webView.addJavascriptInterface(newJsObject(),"injectedObject");webView.loadData("","text/html",null);webView.loadUrl("javascript:alert(injectedObject.toString())");2.传递的方法中,Js获取Java信息可以采用如下方式:importandroid.app.Activity;importandroid.graphics.Bitmap;importandroid.os.Bundle;importandroid.util.Log;importandroid.webkit.WebView;importandroid.webkit.WebViewClient;publicclassHtmlSourceextendsActivity{privateWebViewwebView;@OverridepublicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);webView=(WebView)findViewById(R.id.webview);webView.getSettings().setJavaScriptEnabled(true);webView.addJavascriptInterface(newInJavaScriptLocalObj(),"local_obj");webView.setWebViewClient(newMyWebViewClient());webView.loadUrl("http://www.cnblogs.com/hibraincol/");}最终classMyWebViewClienttextendsWebViewClient{publicbooleanshouldOverrideUrlLoading(WebViewview,Stringurl){view.loadUrl(url);returntrue;}publicvoidonPageStarted(WebViewview,Stringurl,Bitmapfavicon){Log.d("WebView","onPageStarted");super.onPageStarted(view,url,favicon);}publicvoidonPageFinished(WebViewview,Stringurl){Log.d("WebView","onPageFinished");view.loadUrl("javascript:window.local_obj.showSource('
'+"+"文档.getElementsByTagName('html')[0].innerHTML+'');");super.onPageFinished(view,url);}}finalclassInJavaScriptLocalObj{publicvoidshowSource(Stringhtml){Log.d("HTML",html);}}}3.当网页有超链接跳转时,会调用WebClient的shouldOverrideUrlLoading方法。如果设置了WebViewClient,方法返回true,则表示url被应用代码处理,WebView不处理,可以拦截跳转Effect了解了以上几点,我们可以总结出一个比较安全的Java和Js的交互方式:我们可以借鉴AndroidIntent的思想,Java和Js定义一个url格式比如js://_,Java调用Js方法,而在Js方法中通过window.location.href='js://_?key=value#key1=value1'模拟跳转,通过Java的shouldOverrideUrlLoading捕获,函数的返回值可以是放在url参数中。(Js调用Java方法的原理是一样的)这种交互是异步的。如果想知道调用一个Js方法是否有返回值怎么办?一般Java在onPageFinished方法中调用Js方法,在shouldOverrideUrlLoading方法中获取Js返回值。这两个方法有一个共同的参数webview,所以可以先webview.setTag(false),如果返回的结果被抓取,再webview.setTag(false)。setTag(true),postDelayed300毫秒等短时间后,webview.getTag()检查是否有任何变化。