One week ago, Trustlook publised a blog post about the addJavascriptInterface Code execution Vulnerability in Android’s WebView. Accordingly to that post, we describe the attack in detail and also show Android’s changes in the OS in order to mitigate this JavaScript attack.
The usage of WebViews in Android apps is a widely-used approach because of its OS independent development of apps. If an app is developed in form of a web-GUI, it can be easily integrated in any OS-specific app, such as Android, iOS or Blackberry. For instance, Chin et al. [1] analyzed 864 different Android apps in their research, where 608 (70%) of those contained WebViews. This shows that the integration of WebViews is common in Android apps.
Last week, Trustlook published a blog post about a WebView vulnerability in Android that allows an attacker to execute arbitrary code in an application (e.g., install new application on the device) just via a drive-by attack. In this post we want to describe the attack in detail and explain Google’s mitigation against it.
The general idea of this attack is described with the following picture:
- A benign application creates a WebView for displaying web pages.
- These web pages are also allowed to contain JavaScript in it. Therefore the WebView enables the execution of JavaScript.
-
addJavascriptInterface(): By calling this Android API method, an object (in this case: JsInvokeClass) gets injected into the JavaScript context. This allows the Java object’s methods to be accessed from JavaScript. The second argument of that method (“Attack”) is used to expose the object in JavaScript.
- In our example, we directly call an html code via the loadUrl() method. The URL is hard-coded here, but there are other use cases (e.g., browser) where the string is inserted by the user. The html code contains some JavaScript, which is shown in the “JavaScript”-box.
- After 4. the user accesses the web page and the JavaScript gets executed. The JavaScript method execute() accesses the getClass() method of the JsInvokeClass (Attack.getClass()). Since JsInvokeClass is extended from Object, we can call getClass via the supplied name “Attack”. After that we are using reflections to call any Java method. In this case the getRuntime() method in order to execute any command (args). The command in the example is responsible for writing the text “THIS_IS_JUST_A_TEXT” into output.txt (sdcard). Trustlook described a different attack where an app gets built via string concatenation of the app’s binary code that is written into a new file (apk) and gets installed afterwards. If the mobile device is in debug mode, the installation of that new app happens in the background without any user recognition. Quite sexy!
What are the countermeasures and how can a developer mitigate this attack ? Google is aware of this Problem (see API-description) that’s why they introduced the Java Annotation @JavaScriptInterface in Android 4.2. All applications declaring targetsdk >= 17 in the AndroidManifest.xml file that need the interaction between JavaScript and Java have to explicitly annotate those methods that are accessed by the JavaScript. In our case this would cause the annotation of the returnHelloWorld() method in order to call it via JavaScript:
@JavaScriptInterface
public String returnHelloWorld()
All other methods are not able to be access. This is also the reason why our example is no longer working, since the getClass() method is not annotated.
We recommend to declare the targetsdk of their application to version 17 or higher if the interaction between JavaScript an Java is necessary in an app. For older version try to avoid remote injection possibilities by loading JavaScript from remote. Store the JavaScript local in the application or simple try to avoid declaring such interfaces JS calling android API code.
Stephan Huber and Siegfried Rasthofer
[1] Chin, Erika, and David Wagner. “Bifocals: Analyzing WebView Vulnerabilities in Android apps.”
Cross-posted from SEEBlog