JS-Binding-Over-HTTP Vulnerability and JavaScript Sidedoor: Security Risks Affecting Billions of Android App Downloads

Third-party libraries, especially ad libraries, are widely used in
Android apps. Unfortunately, many of them have security and privacy
issues. In this blog, we summarize our findings related to the
insecure usage of JavaScript binding in ad libraries.

First, we describe a widespread security issue with using JavaScript
binding (addJavascriptInterface) and loading WebView
content over HTTP, which allows a network attacker to take control of
the application by hijacking the HTTP traffic. We call this the
JavaScript-Binding-Over-HTTP (JS-Binding-Over-HTTP) vulnerability. Our
analysis shows that, currently, at least 47 percent of the top 40 ad
libraries have this vulnerability in at least one of their versions
that are in active use by popular apps on Google Play.

Second, we describe a new security issue with the JavaScript binding
annotation, which we call JavaScript Sidedoor. Starting with Android
4.2, Google introduced the @JavascriptInterface
annotation to explicitly designate and limit which public methods in
Java objects are accessible from JavaScript. If an ad library uses
@JavascriptInterface annotation to expose
security-sensitive interfaces, and uses HTTP to load content in the
WebView, then an attacker over the network could inject malicious
content into the WebView to misuse the exposed interfaces through the
JS binding annotation. We call these exposed JS binding annotation
interfaces JS sidedoors.

Our analysis shows that these security issues are widespread, have
affected popular apps on Google Play accounting for literally billions
of app downloads. The parties we notified about these issues have been
actively addressing them.

Security Issues with JavaScript Binding over HTTP

Android uses the JavaScript binding method
addJavascriptInterface to enable JavaScript code running
inside a WebView to access the app’s Java methods. However, it is
widely known that this feature, if not used carefully, presents a
potential security risk when running on Android 4.1 or below. As noted
by Google: “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.” [1]

In particular, if an app running on Android 4.1 or below uses the
JavaScript binding method addJavascriptInterface and
loads the content in the WebView over HTTP, then an attacker over the
network could hijack the HTTP traffic, e.g., through WiFi or DNS
hijacking, to inject malicious content into the WebView – and thus
take control over the host application. We call this the
JavaScript-Binding-Over-HTTP (JS-Binding-Over-HTTP) vulnerability. If
an app containing such vulnerability has sensitive Android permissions
such as access to the camera, then a remote attacker could exploit
this vulnerability to perform sensitive tasks such as taking photos or
record video in this case, over the Internet, without a user’s consent.

We have analyzed the top 40 third-party ad libraries (not including
Google Ads) used by Android apps. Among the apps with over 100,000
downloads each on Google Play, over 42 percent of the free apps
currently contain at least one of these top ad libraries. The total
download count of such apps now exceeds 12.4 billion. From our
analysis, at least 47 percent of these top 40 ad
libraries
have at least one version of their code in active
use by popular apps on Google Play, and contain the
JS-Binding-Over-HTTP vulnerability. As an example, InMobi versions
2.5.0 and above use the JavaScript binding method
addJavascriptInterface and load content in the WebView
using HTTP.

Security Issues with JavaScript Binding Annotation

Starting with Android 4.2, Google introduced the
@JavascriptInterface annotation to explicitly designate
and limit which public Java methods in the app are accessible from
JavaScript running inside a WebView. However, note that the
@JavascriptInterface annotation does not provide any
protection for devices using Android 4.1 or below, which is still
running on more than 80 percent of Android devices worldwide.

We discovered a new class of security issues, which we call
JavaScript Sidedoor (JS sidedoor), in ad libraries.
If an ad library uses the @JavascriptInterface annotation
to expose security-sensitive interfaces, and uses HTTP to load content
in the WebView, then it is vulnerable to attacks where an attacker
over the network (e.g., via WIFI or DNS hijacking) could inject
malicious content into the WebView to misuse the interfaces exposed
through the JS binding annotation. We call these exposed JS binding
annotation interfaces JS sidedoors.

For example, starting with version 3.6.2, InMobi added the
@JavascriptInterface JS binding annotation. The list of
exposed methods through the JS binding annotation in InMobi includes:

  • createCalendarEvent (version 3.7.0 and above)
  • makeCall (version 3.6.2 and above)
  • postToSocial (version 3.7.0 and above)
  • sendMail (version 3.6.2 and above)
  • sendSMS (version 3.6.2 and above)
  • takeCameraPicture (version 3.7.0 and above)
  • getGalleryImage (version 3.7.0 and above)
  • registerMicListener (version 3.7.0 and above)

InMobi also provides JavaScript wrappers to these methods in the
JavaScript code served from their ad servers, as shown in Appendix A.

InMobi also loads content in the WebView using HTTP. If an app has
the Android permission CALL_PHONE, and is using InMobi versions 3.6.2
to 4.0.2, an attacker over the network (for example, using Wi-Fi or
DNS hijacking) could abuse the makeCall annotation in the
app to make phone calls on the device without a user’s consent –
including to premium numbers.

In addition, without requiring special Android permissions in the
host app, attackers over the network, via HTTP or DNS hijacking, could
also misuse the aforementioned exposed methods to misguide the user to
post to the user’s social network from the device
(postToSocial in version 3.7.0 and above), send email to
any designated recipient with a pre-crafted title and email body
(sendMail in version 3.6.2 and above), send SMS to
premium numbers (sendSMS in version 3.6.2 and above),
create calendar events on the device (createCalendarEvent
in version 3.7.0 and above), and to take pictures and access the photo
gallery on the device (takeCameraPicture and
getGalleryImage in version 3.7.0 and above). To complete
these actions, the user would need to click on certain consent
buttons. However, as generally known, users are quite vulnerable to
social engineering attacks through which attackers could trick users
to give consent.

We have identified more than 3,000 apps on Google Play that contain
versions 2.5.0 to 4.0.2 of InMobi – and which have over 100,000
downloads each as of December, 2013. Currently, the total download
count for these affected apps is greater than 3.7 billion.

We have informed both Google and InMobi of our findings, and they
have been actively working to address them.

New InMobi Update after FireEye Notification

After we notified the InMobi vendor about these security issues, they
promptly released new SDK versions 4.0.3 and 4.0.4. The 4.0.3 SDK,
marked as “Internal release”, was superseded by 4.0.4 after one day.
The 4.0.4 SDK made the following changes:

  1. Changed its method exposed through annotation for making phone calls
    (makeCall) to require user’s consent.
  2. Added a new storePicture interface to download and save
    specified files from the Internet to the user’s Downloads folder.
    Despite the name, it can be used for any file, not just images.
  3. Compared with InMobi’s earlier versions, we consider change No. 1 as
    an improvement that addresses the aforementioned issue of an attacker
    making phone calls without a user’s consent. We are glad to see that
    InMobi made this change after our notification.

    InMobi recently released a new SDK version 4.1.0. Compared with SDK
    version 4.0.4, we haven’t seen any changes to JS Binding usage from a
    security perspective in this new SDK version 4.1.0.

    Moving Forward: Improving Security for JS Binding in
    Third-party Libraries

    In summary, the insecure usage of JS Binding and JS Binding
    annotations in third-party libraries exposes many apps that contain
    these libraries to security risks.

    App developers and third-party library vendors often focus on new
    features and rich functionalities. However, this needs to be balanced
    with a consideration for security and privacy risks. We propose the
    following to the mobile application development and library vendor community:

    1. Third-party library vendors need to explicitly disclose
      security-sensitive features in their privacy policies and/or their app
      developer SDK guides.
    2. Third-party library vendors need to educate the app developers with
      information, knowledge, and best practices regarding security and
      privacy when leveraging their SDK.
    3. App developers need to use caution when leveraging third-party
      libraries, apply best practices on security and privacy, and in
      particular, avoid misusing vulnerable APIs or packages.
    4. When third-party libraries use JS Binding, we recommend using HTTPS
      for loading content.
    5. Since customers may have different requirements regarding security
      and privacy, apps with JS-Binding-Over-HTTP vulnerabilities and JS
      sidedoors can introduce risks to security-sensitive environments such
      as enterprise networks. FireEye
      Mobile Threat Prevention
      provides protection to our customers
      from these kinds of security threats.

      Acknowledgement

      We thank our team members Adrian Mettler and Zheng Bu for their help
      in writing this blog.

      Appendix A: JavaScript Code Snippets Served from InMobi Ad Servers

      a.takeCameraPicture = function () {

      utilityController.takeCameraPicture()

      };

      a.getGalleryImage = function () {

      utilityController.getGalleryImage()

      };

      a.makeCall = function (f) {

      try {

      utilityController.makeCall(f)

      } catch (d) {

      a.showAlert(“makeCall: ” + d)

      }

      };

      a.sendMail = function (f, d, b) {

      try {

      utilityController.sendMail(f, d, b)

      } catch (c) {

      a.showAlert(“sendMail: ” + c)

      }

      };

      a.sendSMS = function (f, d) {

      try {

      utilityController.sendSMS(f, d)

      } catch (b) {

      a.showAlert(“sendSMS: ” + b)

      }

      };

      a.postToSocial = function (a, c, b, e) {

      a = parseInt(a);

      isNaN(a) &&
      window.mraid.broadcastEvent(“error”, “socialType must
      be an integer”, “postToSocial”);

      “string” != typeof c && (c = “”);

      “string” != typeof b && (b = “”);

      “string” != typeof e && (e = “”);

      utilityController.postToSocial(a, c, b, e)

      };

      a.createCalendarEvent = function (a) {

      “object” != typeof a &&
      window.mraid.broadcastEvent(“error”,

      “createCalendarEvent method expects
      parameter”, “createCalendarEvent”);

      “string” != typeof a.start || “string” !=
      typeof a.end ?

      window.mraid.broadcastEvent(“error”,

      “createCalendarEvent method expects string
      parameters for start and end dates”,

      “createCalendarEvent”) :

      (“string” != typeof a.location &&
      (a.location = “”),

      “string” != typeof a.description
      && (a.description = “”),

      utilityController.createCalendarEvent(a.start,
      a.end, a.location, a.description))

      };

      a.registerMicListener=function() {

      utilityController.registerMicListener()

      };

      Share this post

      Share on facebook
      Share on linkedin
      Share on print
      Share on email

      Subscribe to our Monthly Cyber Security Digest

      Get monthly content to keep you up to date on the latest news and tips