Two Secure Coding Tools for Analyzing Android Apps
This blog post is co-authored by Lori Flynn.
Although the Android Operating System continues to dominate the mobile device market (82 percent of worldwide market share in the third quarter of 2013), applications developed for Android have faced some challenging security issues. For example, applications developed for the Android platform continue to struggle with vulnerabilities, such as activity hijacking, which occurs when a malicious app receives a message (in particular, an intent) that was intended for another app but not explicitly designated for it. The attack can result in leakage of sensitive data or loss of secure control of the affected apps. Another vulnerability is exploited when sensitive information is leaked from a sensitive source to a restricted sink. This blog post is the second in a series that details our work to develop techniques and tools for analyzing code for mobile computing platforms. (A previous blog post, Secure Coding for the Android Platform, describes our team's development of Android rules and guidelines.)
Our work was led by a team of researchers who, in addition to myself, included Dr. Lori Flynn, also of the CERT Secure Coding Team; Dr. Lujo Bauer and Dr. Limin Jia of Carnegie Mellon University's Department of Electrical and Computer Engineering; and Amar Bhosale.
Improving Dataflow Analysis
Our first tool, for which we recently completed building a prototype, addresses a problem often seen in information flow analysis: the leakage of sensitive information from a sensitive source to a restricted sink. "Sink" and "source" are terms common to flow analysis. We define a source as an external resource (external to the app, not necessarily external to the phone) from which data is read and a sink as an external resource to which data is written.
Sometimes the flow of information can be from a highly sensitive source to a place that's not authorized to receive the data. So, the source can be high privilege and the sink can be low privilege. Integrity concerns can also be analyzed using the concept of information flow. Sometimes untrusted data is sent to a place that's supposed to store only high-trusted data that's been sent by an authorized source. If data travels from a low-trust source to a high-trust sink, that's also a problem.
For example, a smartphone user might install an Android game that leaks the user's entire contact list to a marketing company. Of course, government agencies also have their sources of sensitive information and they don't want them to be leaked to unauthorized parties.
We designed and implemented a novel taint flow analyzer (which we call "DidFail") that combines and augments the existing Android dataflow analyses of FlowDroid (which identifies intra-component taint flows) and Epicc (which identifies properties of intents such as its action string) to track both inter-component and intra-component dataflow in a set of Android applications.
Our analysis of a given set of apps takes place in two phases:
- In the first phase, we determine the dataflows enabled individually by each app and the conditions under which these are possible.
- In the second phase, we build on the results of the first phase to enumerate the potentially dangerous data flows enabled by the whole set of applications.
Our tool differs from pure FlowDroid, which analyzes flows of tainted information. FlowDroid focuses on information that flows in a single component of an app; our tool analyzes potentially tainted flows between apps and, within a single app, between multiple components.
Our taint flow analyzer prototype for static analysis of sets of Android apps, DidFail (Droid Intent Data flow Analysis for Information Leakage), was completed in March 2014. Our team is continuing to do research and development with this analyzer, focusing on methods to efficiently increase precision.
Challenges in Our Work
One challenge that we encountered in our work is that while we had access to the full source code for FlowDroid, we could access only the binary code for Epicc. Unfortunately, Epicc produced a list of intents, but did not specify where in the app they originated. To integrate the results of FlowDroid and Epicc, we needed to make Epicc produce this missing information.
Since it wasn't feasible to modify Epicc, we instead modified the Android Application Package File (APK) by tagging each intent with a unique ID so that Epicc would print the intent ID. To do that, we used a function of Soot that enables the instrumentation or transformation of APKs. Soot transformed the binary into Jimple, which is an intermediate representation of a Java program that is Soot-specific. In the Jimple, we looked for intent-sending methods (e.g., methods in the startActivity family) and then inserted new Jimple code that added an extra field (with a unique intent ID number) into the intent. Then, once we processed the APK file, we compiled the Jimple back to Dalvik bytecode and wrote a new, transformed APK file.
Another way of explaining this process is that we wrote a piece of code that takes the original APK and adds a unique identification to each place in the code where the APK sends an intent. The use of unique IDs enabled us to match the output of Epicc with the output of FlowDroid. (We modified FlowDroid to also look for these same intent IDs and print them in its output.) Epicc prints out a list of properties added using the putExtra method. That is how we add the unique ID. It is just a dummy extra field.
Analysis Tool Publication
As of April 2014, we believe that our tool is the most precise (publicly available and/or documented) taint-flow static analysis tool for Android apps. Our tool enables users and organizations to be very secure about the set of apps they allow to be installed together while also enabling them to install the greatest number of apps that abide by their security policy.
This tool is freely available to the public for download along with a small test suite of apps that demonstrates the new analytical functionality it provides. Our recently accepted paper, Android Taint Flow Analysis for App Sets, provides details about the DidFail tool and test results of using it with an Android app set. We encourage you to first read the paper, and then download the DidFail tool and the provided test apps.
The DidFail tool has limitations that we hope to address in future research. These limitations include false positives that are caused by a coarse-grained approach to detecting information flows between apps. A finer-grained analysis could reduce the incidence of false positives. Also, the DidFail tool focuses exclusively on Android intents as the method of data communication across applications. Android apps have other means of communicating including
- directly querying Content Providers
- reading from and writing to an SD card using native code and communication channels (e.g., sockets or the Binder) implemented by the underlying Android Linux operating system
A Tool to Address Activity Hijacking
The second Android app analysis tool, described below, was developed to be part of the CERT Division's Source Code Analysis Laboratory (SCALe) suite of tools for testing code for compliance with CERT secure coding rules. This tool was designed specifically to grow our Mobile SCALe tool set that checks against our new Android-focused secure coding rules and guidelines. This new tool is now part of the CERT Division's compliance checker tool set used for our SCALe code conformance analyses. This tool has been developed for a limited audience and is currently not available for public distribution.
Activity hijacking attacks occur when a malicious app receives a message (an intent) that was intended for another app, but not explicitly designated for it. In the Android middleware, intents are the primary means of inter-app communication and may include a designation of the recipient, an action string, and other data.
If no recipient is designated in an activity intent, then Android tries to find a suitable recipient (e.g., an app that declares in an intent filter in its manifest file that it can handle the specified action string). If there are multiple suitable apps, then Android prompts the user to select which one to use. The user can also designate the chosen recipient as the default to handle all similar intents (e.g., intents with the same action string) in the future and thwart hijacking attempts.
However, a malicious app can trick the user by using a confusing name. In addition, an inattentive user might not give much thought to the choice. Moreover, the device's touch screen might register a click for the malicious app that the user did not intend. Android does not require confirmation of the user's selection (which would be helpful in mitigating accidental clicks), even though such an accidental click can irreversibly leak sensitive information. An implicit intent is an intent that does not specifically designate a recipient component by its fully qualified class name, as opposed to an explicit intent, which does. Only implicit intents are vulnerable to activity hijacking.
In addition to inter-app communication, intents are also used for intra-app communication between different components of a single app. The use of implicit intents for intra-app communication has proved to be a common mistake in the development of Android apps, as well as a violation of our secure coding rules. A component might intend to communicate with another component in the same application, but if that component uses an implicit intent (instead of an explicit intent), it might be vulnerable to another app intercepting its message.
Unfortunately, it is easy for a developer to mistakenly make app interfaces public when they should be private, allowing malicious apps to hijack or eavesdrop on apps that have access to sensitive information or resources. Moreover, closely related apps may have been developed to send intents to each other without explicitly designating the recipient, leaving open an avenue for activity hijacking.
In the technical report that the SEI published describing our work on this tool, Mobile SCALe: Rules and Analysis for Secure Java and Android Coding, we detail the design and implementation of our tool, which was constructed using the Soot Java analysis framework. Our tool identifies the method calls that send Android intents. Where possible, our tool identifies the action string associated with the intent and the target of the intent in the case of an explicit intent.
Our activity hijacking vulnerability detection tool analyzes each app individually to
- find likely violations of secure coding rules
- produce a list of the different types of intents the app registers receive
- produce a list of program sites (source code or bytecode locations) that send intents, along with the action string and target class if known
Our goal with this series of blog posts is to share the progress on our Mobile SCALe project work, thereby extending the existing CERT SCALe conformance process to create a source code analysis laboratory environment for mobile computing platforms. This blog post is intended to update you on our work on the Android operating system, the first area of focus for Mobile SCALe.
Our team is currently at work on improving our tool that looks for information flows where the data source is sensitive and the sink is restricted. The research challenge we're focusing on is to develop an analysis to determine taint flow endpoints with the following (sometimes conflicting) goals in mind: precision, soundness, and the ability to operate within resource limitations (i.e., time and memory).
We welcome feedback on our work. Please leave comments below.
To download the DidFail tool, please visit
Read the SEI technical report, Mobile SCALe: Rules and Analysis for Secure Java and Android Coding, for more information about the work described in this blog post.