Android Attack: JavaScript Interfaces and WebViews

Estimated difficulty: 💜💜🤍🤍🤍

This post will walk you through what a JavaScript interface is and how you might retrieve the Java object from the application into the application WebView using this method.

A WebView is pretty much what it says on the tin. Android applications can define a WebView within an Activity class in order to display content pulled from the internet. This could be your very own website’s web page, such as a contact form. the application must have the internet permission, in order to talk to the website that is being pulled into the Android application’s WebView.

Most websites are built using an array of different web languages, and one of the most popular ones is JavaScript. We can add a JavaScript interface to our application’s Java code, to allow the JavaScript of a webpage to interact with the Java application code. To ensure the JavaScript can execute, you need to make sure that you setJavaScriptEnabled.

What is a JavaScript Interface

A JavaScript Interface (JSI) is used to invoke and talk to native objects/modules that are used in the Java/ObjC code. To define a JavaScript interface you need to use the method addJavaScriptInterface().

Only public methods that are annotated with JavascriptInterface can be accessed from JavaScript.

Android Developers

The best way to explain a JavaScript Interface being used in an Android application is to show you! For this, I am using Code Project’s example, as it is clear, easy to understand, and purely because we do not need to reinvent the wheel.

When an Android application uses a JavaScript Interface, it needs to add it by using the method call ‘addJavascriptInterface‘. In the below Java code example, we can see the interface ‘AndroidFunction‘ being added. ‘AndroidFunction‘ will be used in the JavaScript code to interact with the functions defined in the application code.

The below code would be found in the MainActivity class of an Android Application. If you are not familiar with what an activity is, then check out my post, What in the APK?!.

package my.demo;
import my.demo.R;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.webkit.WebView;
import android.widget.TextView;
import android.widget.Toast;


public class MainActivity extends Activity {
	private WebView Wv;
	private TextView myTextView;	
	final Handler myHandler = new Handler();
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       
        setContentView(R.layout.main);
        Wv = (WebView)findViewById(R.id.webView1);
        myTextView = (TextView)findViewById(R.id.textView1);        
        final JavaScriptInterface MyJavaScriptInterface
     	= new JavaScriptInterface(this);    	 
    	 
        Wv.getSettings().setLightTouchEnabled(true);
        Wv.getSettings().setJavaScriptEnabled(true);
        Wv.addJavascriptInterface(MyJavaScriptInterface, "AndroidFunction");
        Wv.loadUrl("file:///android_asset/index.html"); 
    }

The line below, shows a new JavaScript Interface being added.

Wv.addJavascriptInterface(MyJavaScriptInterface, "AndroidFunction");

The ‘MyJavaScriptInterface‘ interface will link to a class in the android application code. This class can contain the methods that the JavaScript will try to invoke. Let’s take a look at that example class below. The ‘AndroidFunction‘ string is the name of the interface that will be called in the application code.

public class MyJavaScriptInterface {

  Context mContext;
  MyJavaScriptInterface(Context c) {
     mContext = c;
  }

  @JavascriptInterface
  fun showToast() {
    String webMessage = new String("Hello World!");
    Toast.makeText(mContext, webMessage, Toast.LENGTH_SHORT).show();
  }
}

The ‘loadUrl‘ method call, found in the MainActivity class, can specify the URL, JavaScript or even HTML file that will be loaded into the web view. In this example, the JavaScript in the index.html file being loaded may be able to invoke the Java method ‘showToast‘ using the JavaScript Interface. In this case, the ‘index.html‘ file was stored in the android assets resources directory.

Wv.loadUrl("file:///android_asset/index.html");

An example of what the ‘index.html‘ file contents could look like, has been shown below.

<!DOCTYPE >
<html xmlns="http://www.w3.org/1999/xhtml" debug="true">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <meta name="viewport" 
          content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
        <meta name="apple-mobile-web-app-capable" content="yes">
        <meta name="viewport" content="target-densitydpi=device-dpi" />
        <script type="text/javascript">
           function init()
           {
        	   var testVal = document.getElementById('mytextId').value;
        	   AndroidFunction.showToast(testVal);
           }
        </script>
    </head>
    <body>        
        <div style="float: left;width: 50%;">
           <input type="text" style="width: 180px;" 
                   name="myText" id="mytextId" />
           
        </div>
        <div style="clear: both;height: 3px;"> </div>
        <div>
          <input value="submit" type="button" name="submit" 
            id="btnSubmit" onclick="javascript:return init();" /> 
        </div>  
    </body>
</html>

The ‘showToast‘ function in the Android application code, is called by the HTML being loaded in the ‘init()‘ function. Once the WebView is loaded and if the script is executed, then the application will show a toast message in the refreshed WebView of the application.

AndroidFunction.showToast(testVal);

Note that the ‘AndroidFunction‘ JavaScript Interface has the same name as that in the MainActivity class found in the application code in the ‘addJavaScriptInterface‘ method call. That is an introductory look at how JavaScript interfaces work! Imagine this being used in a number of scenarios and not always used for good…

Security Implications

Research has been done into the vulnerabilities of JavaScript interfaces and how they can be exploited to achieve remote code execution (RCE).

The WebView JavaScript bridge can be abused to execute arbitrary Java code, by using reflection to acquire a reference to a runtime object via the interface implemented in the Java code.

W/ Labs
Source: ZNet

The researchers identified that they could attempt to inject the below script into a WebView implementing a native bridge using android.webkit.JavascriptInterface to execute operating system commands.

<script>
function execute(cmd){
return window.jsinterface.getClass().forName('java.lang.Runtime').getMethod('getRuntime',null).invoke(null,null).exec(cmd);
}
execute(['/system/bin/sh','-c','echo \"mwr\" > /mnt/sdcard/mwr.txt']);
</script>

The script uses the JavaScript interface to get the Runtime class of the application and execute the command “cmd“. It will try to execute an echo command and append it to a txt file.

Check out the publication for more information.

Furthermore, HackTricks has also written a post about how to attack WebViews when performing an Android application pen test.


Thank you for reading this post! I hope it has helped you in your journey to understand Android applications even more.

Have a fab Friday!

Sarah <3

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.