Arbitrary function invocation on Android WebViews

The WebView is one of the riskiest parts of an Android app if not set up correctly. It can cause many problems, like letting attackers change URLs or even execute code remotely. Unlike typical Android components, WebView can execute web content, making it more prone to attacks from different actors, including JavaScript injection and insecure data handling. Let’s have a look at how malicious attackers could perform arbitrary function invocation on WebViews, exploiting JavaScript interfaces.

JavaScript Interfaces

A few years ago, while I was working in a project that relied heavily on WebViews, I wrote this article showing how you could write JavaScript interfaces to execute some business logic on Android WebViews. Unfortunately, that article does not consider the security problems that come with such approach. Let’s see one simple example:

WebView webView = new WebView(this);
setContentView(webView);
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new JavaScriptHandler(), "AndroidHandler");

Where the JavaScriptHandler would look like:

public class JavaScriptHandler {
        public void clearUserData(String id) {
            DB.deleteAllDataForUser(id)
        }
    }

While from the developers perspective, it might look safe since they are rendering the html file themselves,

webView.loadURL("http://www.example.com/user_options.html");

this approach is vulnerable to MITM (man in the middle) attacks.

Suppose the html would look like this:

<!DOCTYPE html>
<html lang="en">
<head>
    ...
</head>
<body>
    <h1>Welcome to profile!</h1>
    <p>Click the button below:</p>
    <button onclick="AndroidHandler.clearUserData('1234');">
        Click Me
    </button>
</body>
</html>

Using tools like BurpSuite this call can easily be intercepted and manipulated, transforming the HTML file from what it is supposed to be, to:

<!DOCTYPE html>
<html lang="en">
<head>
    ...
</head>
    <script>AndroidHandler.clearUserData('1234');</script>
</body>
</html>

With minimal effort, a malicious actor could delete user data without their consent, potentially causing a denial of service. This might force the user to repeatedly log in and out, leading to confusion before realizing something is wrong.

Note: The JavaScript interface would remain insecure, even if solutions like SSL pinning would be introduced.

Hopefully, this example sheds light on one of the many ways vulnerable Android WebViews can be exploited. In my opinion, WebViews should be limited to simple and basic tasks. When business logic is involved, developers must carefully consider what they implement. Weak implementations often arise from low-budget projects or tight deadlines, but sacrificing security for time or money can have serious consequences in the long run. Investing time and resources upfront to ensure proper security can prevent costly breaches later on.

Do you have security concerns about your mobile app and would like me to take a look? As an independent Android pentester, I offer security assessments to help identify vulnerabilities. Feel free to reach out if you’d like a thorough review to ensure your app is secure and resilient against potential threats.