Android Webview Java and Javascript safe interaction

Android Webview Java and Javascript safe interaction

Recently, I need to detect the source code of a web page. There is no direct interface to obtain the source code of the web page in Android Webview. The traditional addJavascriptInterface method has security risks, so I studied the security interaction between Java and Javascript.

Android Webview Vulnerability

Android Webview has two very well-known vulnerabilities:

  • The recently exposed UXSS vulnerability can bypass the same-origin policy and obtain the cookies and other information of any web page. This problem exists on Android 4.4 and below, and there is basically no solution. It can only be solved by recompiling the browser kernel. For details, please refer to the recent mobile security events. If you are interested, you can watch the video of @RAyH4c hijacking Weibo and QQ space.
  • The long-known arbitrary command execution vulnerability, through the addJavascriptInterface method, Js can call Java object methods, through the reflection mechanism, Js can directly obtain the Runtime, and thus execute arbitrary commands. For Android 4.2 and above, you can ensure security by declaring @JavascriptInterface. For Android 4.2 and below, you can no longer call addJavascriptInterface, and you need to find another way.

Safe interaction between Java and Javascript

First of all, a few points:

1. It is easy to call Js methods from Java in Android Webview. loadUrl("javascript:isOk()") can call the isOk Js method, but the return result of the Js method cannot be directly obtained.

  1. class JsObject {
  2. @JavascriptInterface  
  3. public String toString() { return   "injectedObject" ; }
  4. }
  5. webView.addJavascriptInterface( new JsObject(), "injectedObject" );
  6. webView.loadData( "" , "text/html" , null );
  7. webView.loadUrl( "javascript:alert(injectedObject.toString())" );

2. In the traditional method, Js can obtain Java information in the following ways:

  1. import android.app.Activity;
  2. import android.graphics.Bitmap;
  3. import android.os.Bundle;
  4. import android.util.Log;
  5. import android.webkit.WebView;
  6. import android.webkit.WebViewClient;
  7.  
  8. public   class HtmlSource extends Activity {
  9. private WebView webView;
  10.  
  11. @Override  
  12. public   void onCreate(Bundle savedInstanceState) {
  13. super .onCreate(savedInstanceState);
  14. setContentView(R.layout.main);
  15. webView = (WebView)findViewById(R.id.webview);
  16. webView.getSettings().setJavaScriptEnabled( true );
  17. webView.addJavascriptInterface( new InJavaScriptLocalObj(), "local_obj" );
  18. webView.setWebViewClient( new MyWebViewClient());
  19. webView.loadUrl( "http://www.cnblogs.com/hibraincol/" );
  20. }
  21.  
  22.  
  23. final   class MyWebViewClient extends WebViewClient{
  24. public   boolean shouldOverrideUrlLoading(WebView view, String url) {
  25. view.loadUrl(url);
  26. return   true ;
  27. }
  28. public   void onPageStarted(WebView view, String url, Bitmap favicon) {
  29. Log.d( "WebView" , "onPageStarted" );
  30. super .onPageStarted(view, url, favicon);
  31. }
  32. public   void onPageFinished(WebView view, String url) {
  33. Log.d( "WebView" , "onPageFinished " );
  34. view.loadUrl( "javascript:window.local_obj.showSource('<head>'+" +
  35. "document.getElementsByTagName('html')[0].innerHTML+'</head>');" );
  36. super .onPageFinished(view, url);
  37. }
  38. }
  39.  
  40. final   class InJavaScriptLocalObj {
  41.  
  42. public   void showSource(String html) {
  43. Log.d( "HTML" , html);
  44. }
  45. }
  46. }

3. When there is a hyperlink jump in the web page, the shouldOverrideUrlLoading method of WebClient will be called. If WebViewClient is set and the method returns true, it means that the URL is processed by the application code and WebView does not, which can achieve the effect of intercepting the jump.

Understanding the above points, we can summarize a relatively safe way for Java and Js to interact :

We can learn from the idea of ​​Android Intent. Java and Js define a URL format such as js://_. Java calls the Js method. In the Js method, window.location.href='js://_?key=value#key1=value1' is used to simulate the jump. It is captured by Java's shouldOverrideUrlLoading. The return value of the function can be placed in the URL parameter. (The principle of Js calling Java methods is the same)

This interaction method is asynchronous. What if you want to know whether calling a Js method returns a value? Generally, Java calls the Js method in the onPageFinished method, and obtains the Js return value in the shouldOverrideUrlLoading method. The two methods have a common parameter webview, so you can first call webview.setTag(false). If the return result is captured, then call webview.setTag(true). After a short time, such as 300 milliseconds, call webview.getTag() to check whether there is any change.

<<:  Changsi Advertising won the "Golden Coordinate" 2014 Best Mobile Advertising Platform Award

>>:  Which three “mobile industry chains” has WeChat created?

Recommend

iOS vs Android Development — How Do We Choose?

【51CTO.com Quick Translation】I believe many of yo...

Pinduoduo’s “Reading Month” Plan

Argentine writer Borges once said: "If there...

HTML5 gesture detection principle and implementation

Preface With the richness of hybrid applications,...

Ford calls for equal treatment in the UK against favouring Nissan

Recently, Ford Europe CEO Jim Farley will meet wi...

These 11 bad habits are disease "catalysts"! How many of them are you among?

The emergence of diseases is sometimes closely re...

Google can't kill Android, but it can put it into hibernation

[[225212]] Editor's note: Does Google's r...

What are the essential elements for a perfect event planning program?

Do you hope that the event will become a hit? Tha...