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