JS-Binding-Over-HTTP Vulnerability and JavaScript Sidedoor: Security Risks Affecting Billions of Android App Downloads
January 17 2014Third-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:
- Changed its method exposed through annotation for making phone
    calls (makeCall) to require user’s consent.
- Added a new storePictureinterface 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.
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:
- Third-party library vendors need to explicitly disclose security-sensitive features in their privacy policies and/or their app developer SDK guides.
- Third-party library vendors need to educate the app developers with information, knowledge, and best practices regarding security and privacy when leveraging their SDK.
- 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.
- When third-party libraries use JS Binding, we recommend using HTTPS for loading content.
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()
};
						
						
						                
                        
                
                     
							
					
					                
 
						 
                         
                        