Mobile devices such as smartphones and tablets are critical tools that billions of users worldwide depend on for a variety of needs: communications, banking, news, navigation, and entertainment, among many others. A diverse ecosystem of third-party apps enables this versatility by utilizing rich telecommunications, data processing, and sensing capabilities common on mobile devices. These capabilities, combined with users’ heavy reliance on these platforms, result in mobile devices holding a vast amount of highly sensitive personal data that apps can access.
Mobile operating systems such as Android implement permissions to mitigate the risk of apps misusing sensitive data. Android’s permission system gives users control over what sensitive resources apps may access. For example, permissions regulate access to the user’s contact list, current location, and SMSs. However, recent investigations into mobile privacy have found issues in the usability and effectiveness of existing permission systems: apps can circumvent permissions; users’ privacy preferences are contextually dependent; and invisible third-party services embedded in apps account for the bulk of private data collection. Android’s permission system provides insufficient transparency and control given the realities of the mobile app ecosystem and actual user expectations.
Privacy Enhancements for Android (PE for Android) is a platform for exploring concepts in regulating access to private information on mobile devices. Our goal is to create an extensible privacy system that abstracts away the details of various privacy-preserving technologies. We strive to allow app developers to safely leverage state-of-the-art privacy techniques without knowledge of esoteric underlying technologies. Additionally, PE for Android helps users to take ownership of their private information by presenting them with more intuitive controls and permission enforcement. We developed PE for Android as a fork of the Android Open Source Project (AOSP) release for Android 9 “Pie.” This effort modified 13 of Android 9’s Git repositories and added 2 new repositories of supplemental resources to the code base.
PE for Android is a set of extensions and interfaces integrated into the Android OS, similar to Google Play services and SE for Android. Our platform introduces new APIs, services, and a Privacy Abstraction Layer (PAL). The goal of these components is to move sensitive data processing out of the application process space, and into these new services that implement privacy preserving technologies. Once the sensitive information is transformed it may then be returned to the application.
As shown in Figure 1, these APIs facilitate the development of swappable components invoked when apps request private data. This includes Policy Managers that can log and help users make informed decisions about requests to access to sensitive information. Further, PE for Android offers the Private Data Service and associated modules dubbed μPALs, which transform private data into less sensitive forms (e.g., from full-resolution GPS coordinates to just a zip code). This modular architecture allows for the experimentation of various models for how apps consume sensitive data and how users can gain insight into their use.
Policy Managers regulate all access to dangerous permissions on the system, as well as requests issued to the Private Data Service. In making these decisions, Policy Managers operate on run-time contextual factors such as the calling app, its visibility, and (if specified by the app developer) the purpose for the data request. Policy Managers also receive information about app metadata, declared permissions, and developer-set policies at install time. Developers and researchers can rapidly implement various permissions models as Policy Managers. Policy Managers are user-space Android apps, which eliminates the need to modify permissions logic within the Android platform itself. PE for Android allows users to install multiple Policy Managers and select the active one without needing to re-provision the device.
In lieu of existing permission-controlled APIs like LocationManager, apps targeting PE for Android can opt to send requests for sensitive data to the Private Data Service. Through this, apps obtain the information they need in a “least privileges” manner, and do so without inadvertently extending overly broad permissions to bundled third-party services. The Private Data Service is the entry point for the data transformation and isolation techniques implemented by a μPAL. The Private Data Service and associated μPALs are a collection of trusted processes responsible for the direct access of sensitive resources (e.g., high-accuracy geolocation data) and the subsequent extraction of reduced-resolution information the app needs (e.g., a zip code for a weather app). This model eliminates the need for apps to have direct access to private data otherwise exposed by the stock Android API.
Although Policy Managers and μPALs don’t necessarily have direct access to sensitive data via the system API, PE for Android still places restrictions on the installation of these trusted components. Thus, developers must sign their Policy Manager and μPAL binaries with the PE for Android platform key to authorize its installation. The platform blocks the installation of improperly signed components. This mechanism allows for trusted third-party developers to contribute to the PE for Android ecosystem, while still enforcing a degree of review and curation on what Policy Managers and μPAL modules can do.
We implemented some examples to illustrate practical use-cases for our platform’s various capabilities: instrumenting the permission system, performing privacy transformations on sensitive data, and integrating with existing applications without reducing functionality.
Policy Manager: Privacy Checkup
A major potential use case for Policy Managers is in providing transparency into when and how apps request access to sensitive data. We offer the Privacy Checkup tool as a functional proof-of-concept for this application. The Privacy Checkup logs all dangerous permission requests and μPAL calls, then offers historical statistics to the user. This gives the users insight into when apps are accessing sensitive pieces of information, and particularly if that behavior occurred invisibly in the background. The Privacy Checkup continues to capture app activity when users are in other apps and even when the phone is idle with the screen off.
This tool presents both raw access counts and minute-by-minute activity. A user gains insight into when apps are collecting sensitive data unexpectedly; for example, when a keyboard app is polling the contact list even when the user is doing something else (as shown in Figure 2). With this knowledge, users can use the built-in policy editor (shown below in Figure 3) to restrict when individual apps can receive particular permissions; in this example preventing the Facebook Messenger app from accessing the microphone.
Source code for Privacy Checkup is available here.
μPal Module: Phone number –> name
System API data source: contact list
App-provided parameter (required): known phone number or known name
This μPAL module allows apps to retrieve the corresponding name given a known phone number, and do so without exposing the whole contact list to the app. The calling app assembles a request for contact list data and includes a known number, which the μPAL module uses for this cross-referencing operation.
Source code available here.
μPal Module: Fine location –> zip code
System API data source: geolocation functionality
App-provided parameter (optional): location provider
This μPAL module allows apps to receive rough (US zip-code level) location data without getting the user’s exact location. The calling app issues a request for geolocation data and optionally specifies a location provider (e.g., satellites, cell towers, wi-fi routers, last known, or fused). The μPAL receives this data and performs a local lookup to report the US zip code for the current location, if it exists.
Source code available here.
The Signal Private Messenger is an end-to-end encrypted instant messaging service that operates on a variety of platforms including Android. As a communications app, Signal reads the user’s contact list to help connect them to the people they know. As a result, the stock Android implementation of permissions and contact list APIs allows Signal to access the user’s entire contact list.
We sought to eliminate the permissions GET_ACCOUNTS, READ_CONTACTS, and WRITE_CONTACTS from Signal’s manifest. These permissions expose sensitive data that we deemed overly broad and unnecessary for a privacy oriented messaging app. To that end, we used the PAL architecture and Android’s built-in trusted contacts picker to give Signal the contact information it needs, but only for contacts the user selects.
We first removed those permissions from the manifest and discovered that Signal handles permission denials gracefully. When Signal does not have permission to access the contact list, its built-in contact picker guides the user to the settings that would allow the user to grant it. In the official version of Signal, the “Show Contacts” button displays those settings as shown in the rightmost screenshot in Figure 4 below.
We redirected the “Show Contacts” button to instead issue an Intent to call Android’s built-in contact picker. The contact picker is a system-provided Activity that operates outside of Signal’s process space. This means that only the picker can read the user’s full contact list, and Signal only receives what the user selects. Upon the user’s selection, the picker sends one contact to Signal, whose phone number we place in the search box (as if the user had manually typed it in) as shown in Figure 5.
Users expect their contacts’ names to appear in the UI, as names are more usable to humans than raw phone numbers. The contact picker only sends a phone number to Signal. In order to get the contact’s name, we modified Signal to use the PAL paradigm: Signal makes a request for a “phone-number-to-name” μPAL module to receive the full contact list and an app-provided phone number (i.e., what the user had previously selected), then return the name associated with that phone number if it exists. Our modifications save the name and phone number in Signal’s internal database, which Signal subsequently uses to populate the messaging UI, as shown below in Figure 6. Note that if the user received a message from a user who did not associate their name with Signal, this same μPAL module could be used to look up the sender’s name based on their phone number.
We implemented these changes and verified that our modified version of Signal continues to function properly with the Signal network. We successfully sent and received messages between our modified Signal and peers running stock versions of the Signal app on Android, iOS, and Linux.
Source code available here.
Weather apps have been implicated in the unexpected collection and use of consumers’ location data. Most request the ACCESS_FINE_LOCATION permission, which gives apps access to the device’s true location within a few meters. Even with the less-accurate ACCESS_COARSE_LOCATION, apps can still get the location within approximately 100 meters. Location-enabled apps have access to much higher resolution location information than what’s necessary to provide a weather forecast. We sought to alleviate this problem using the PAL architecture.
Forcastie is an open-source weather app for Android that queries forecast information using public OpenWeatherMap APIs. In its normal implementation, Forcastie requests the user’s high accuracy location, then queries OpenWeatherMap using the latitude and longitude of the device. This exposes the user’s location to both the Forcastie app and the backend weather service. To reduce the fidelity of the user’s location information that is exposed, we modified Forcastie to get forecast information using only the zip code of the user’s current location. The changes required for this were minimal. First, we replaced the code that requested Location (through the standard LocationManager APIs) with a call to our “zip-code” μPAL module. Then, we changed the call to OpenWeatherMaps from an API that uses latitude and longitude to one that uses zip code.
As shown in Figure 7, with these small modifications, we were able to remove the Location permission from Forcastie, and greatly reduce the fidelity of location information that both the app and the backend weather service receive. Additionally, because the zip code μPAL uses a local database to perform the lookup converting a precise location to a zip code, the specific latitude longitude coordinates of the user are never sent off the device.
Source code available here.
For more details, please refer to the full PE for Android whitepaper.