Mobile App Data Privacy – the Example

In November of 2013 our research team spent some time reverse engineering popular mobile applications to get some practice reversing interesting apps. After reviewing these types of apps we noticed a trend that some messaging apps did not take any steps to ensure confidentiality of their locally stored messages. In light of similar issues having recently been deemed a concern on other platforms we thought we’d publish one of our examples to increase user awareness of such behaviors.

The application we’re discussing here is free email service’s mobile client offered by Microsoft. This app is described as being created by Seven Networks in conjunction or in association with Microsoft (i.e. looks like it was outsourced.) The app allows users to access their email on Android devices. In the course of our research we found that the on-device email storage doesn’t really make any effort to ensure confidentiality of messages and attachments within the phone filesystem itself. After notifying Microsoft (vendor notification timeline is found at the end of this post) they disagreed that our concern was a direct responsibility of their software, in light of similar problems with iOS being deemed a concern by privacy advocates we thought it’d be a good idea to share what we see with the app.

Root Cause: A Common Problem with the Privacy of Mobile Messaging Messaging Apps

We feel a key security and privacy attribute of any mobile messaging application is the ability to maintain the confidentiality of data stored on the device the app runs on. If a device is stolen or compromised, a 3rd party may try to obtain access to locally cached messages  (in this case emails and attachments). We’ve found that many messaging applications (stored email or IM/chat apps) store their messages in a way that makes it easy for rogue apps or 3rd parties with physical access to the mobile device to obtain access to the messages. This may be counter to a common user expectation that entering a PIN to “protect” their application would also protect the confidentiality of their messages. At the very least app vendors can warn a user and suggest that they encrypt the file system as the application provides no assurance of confidentiality. Or take it the next level and proactively work with the user to encrypto filesystems at installation time.

The Mobile App Behaviors

We’ve found the following two behaviors of the app:

  • The email attachments are stored in a file system area that is accessible to any application or to 3rd parties who have physical access to the phone.
  • The emails themselves are stored on the app-specific filesystem, and the “Pincode” feature of the app only protects the Graphical User Interface, it does nothing to ensure the confidentiality of messages on the filesystem of the mobile device.

We feel users should be aware of cases like this as they often expect that their phone’s emails are “protected” when using mobile messaging applications.

Recommendations to Users

We recommend the setting Settings => Developer Options => USB debugging be turned OFF. We further recommend using Full Disk Encryption for Android and SDcard file systems. This would prevent a 3rd party from getting access to any data in plain-text, from a messaging app or other apps that may choose to store private data on the SDCard.

Users may change the email attachments download directory, via Settings->general->Attachments Settings->Attachment Folder. It is advised not to set the download directory for attachments to be /sdcard/external_sd, as this will place email attachments on the removable SDCard (if one is in place).

For the tech and security folks reading this post, we’ll now dive into how we investigated these software behaviors……

Behavior #1: Attachments are placed in a possibly world-readable folder. for Android downloads email attachments to the SDcard partition by default. For almost all versions of Android this places the attachments in a world-readable folder. This would place downloaded email attachments in a storage area accessible to any user or application which can access the SDcard (e.g any app granted READ_EXTERNAL_STORAGE permission) – even if the phone was not rooted. A 3rd party would simply use ADB shell in order to find the attachments, which are located in /sdcard/attachments:

/sdcard/attachments and files inside are word readable on a device running Android 4.0.4.

The attachments can then be pulled from the device using ADB.
Bas Bosschert in his post shows how files from the SDcard may be uploaded to a server.  Hence using a similar technique a rogue application needs only the READ_EXTERNAL_STORAGE and INTERNET permissions to exfiltrate data from the SDcard to the Internet, these permissions are some of the most common permissions granted by users to applications upon installation.

Users of the latest Android 4.4 or later devices would not see this behavior as having security/privacy ramifications since the SDcard partition is not world readable on Android 4.4 and above. However note that Android 4.4 was released on October 31, 2013 and at the time of this writing a large market share of devices are not running this latest version of Android OS.

Behavior #2: Pincode does not  protect/encrypt downloaded emails or attachments. provides a Pincode feature. When activated, users have to enter a code in order to interact with the application (launch it, resume it, etc). This feature is not enabled by default in the application: the user must manually enable this feature. We’ve found that the Pincode feature does not encrypt the underlying data, it only protects the Graphical User Interface, and we feel this is a behavior users should be aware of. This is something that a lot of people reading this blog might think is obvious, but we surveyed a couple non-tech users (hi mom!) and found that the expectation of privacy for the Pincode feature was present. Meaning the user expected that the Pincode would “…protect the whole thing, including the emails” -Mom.

A user manually creates the pincode after installation.

After 10 wrong pincode attempts the app will delete the account:

An incorrect Pincode is entered.

The Pincode functionality is located in the class. When a Pincode is created it is passed to AppLock.createHashedPassword(). This creates a custom Base64 encoded SHA1 of the passcode which is stored in the preferences cache (in AppLock.saveHashPassword()). Whenever a Pincode is entered to unlock the app, the same custom Base64 encoded SHA1 is applied to the Pincode and then compared to the stored value for the unlock to succeed (method call: AppLock.testMatchExistingPassword(), called from AppLockPasswordEntry.validatePassword()).

The Pincode is sufficient to stop a party who only will try to access the outlook client via the phone screen interface. It will not prevent a party who  has access to the filesystem on the device via USB (e.g. ADB). If USB Debugging is enabled and the device is rooted a 3rd party would be able to access the cached emails database. The 3rd party would simply have to run ADB shell to navigate to the working directory of the application (which is /data/data/com.outlook.Z7) in order to find the databases folder:

Cached email is stored in an SQLite database located at /data/data/com.outlook.Z7/databases/email.db. 

A 3rd party could retrieve the email database file from a rooted phone via standard use of the adb utility. Or the backup trick outlined by Sergei Shvetsov would allow access to the app specific filesystem on a non-rooted mobile device by using an adb trick. First the email.db would have to be removed from the phone via adb and then the relevant data could be accessed by a utility such as sqlite3 (this whole thing can be automated to execute instantly)

Email bodies are stored in two tables, a plaintext Preview table containing a short snippet of the email, and a html_body table containing the full email including html markup.

Extraction of sensitive data is simpler if the sensitive data is in a short email or at the beginning of a long email, since the first few lines of the email will be placed in plain-text in the Preview column. In this example we have pulled out the body of an email from the Preview table in the database. In the example below we read a specific email (email _id #20) instead of dumping out all emails previews.

Example of reading a short email containing confidential data on the database via sqlite3.

If the email is longer than the Preview will store, this is not a problem, we just have to pull out the email and then read the html with something sane:

Email #18 was crafted to contain a large bit of text from wikipedia with credentials added to the end.

Using a web browser to read the emails stored in the html_body table.

To read out the entire email spools just remove the WHERE clause from above; the WHERE clause was merely added for brevity.

Recommendations for Mobile App Developers

A good defensive measure would be to check the mobile device to see if encryption is enabled by calling getSystemServer() to obtain a DevicePolicyManager object, and then query that object with getStorageEncryptionStatus() to check if the device is encrypted with native filesystem encryption.

If the device is not encrypted, the application might show a prompt to ask the user if they’d like to apply Full Disk Encryption to both the device and the SDcard or accept the risk of not having encrypted filesystem before storing data in the for Android application.

Alternatively; the for Android app could use 3rd party addons (such as SQLcipher) to encrypt the SQLite database in tandem with transmitting the attachments as opaque binary blobs to ensure that the attachments can only be read by the app (perhaps using the JOBB tool). These methods would be useful for older devices (such as devices that run Android 4.0 and earlier) that do not support full disk encryption.

Digital Forensics Notes

Digital Forensics technicians interested in obtaining the account information for investigations would take note of the following information.
  • The application working directory on the android device is located at: /data/data/com.outlook.Z7
  • The subdirectories contain the following information:
    • cache/ – contains the various webcaches for content being pulled into webviews.
    • databases/ – contains the database files where the content of messages, emails, and contact lists are kept
    • files/ – log files for the client and the engine
    • lib/ – empty
    • shared_preferences/ – contain xml files which reflect the state of the user options on the client
  • The account email username is kept in the file: /data/data/com.outlook.Z7/shared_prefs/com.outlook.Z7_preferences.xml
  • The username can be found by searching for the string “email_addresses” in that file.
  • The actual human name of the account is stored in the log files located at: /data/data/com.outlook.Z7/files Looking for the string “connector” within the files in that directory will show the name and account information.
  • Technicians should be able to retrieve the emails by rooting the phone and retrieving the file at: /data/data/com.outlook.Z7/databases/email.db
  • Once rooted, attachments can be found in the folder: /sdcard/Attachments/
  • The default email address may also be found by looking for the string “email_default_from_address” in the file: /data/data/com.outlook.Z7/shared_prefs/com.outlook.Z7_preferences.xml
Also note that contacts and messages are also stored in the email.db database which may contain additional proof of a communication between two parties.

Message content and contact information are stored in the email.db.

Lost Feature: Encryption?

We discovered the following which may indicate a possible future role for encryption in the app.

The DecryptingSQLiteCursor implementation could be used to decrypt items in a database column (such as email contents).
In order to test the extent of the “in place” encryption infrastructure, we decided to force-enable encryption by changing the value of Z7MetaData.ClientConfig.UseEncryption in the AndroidManifest.xml to true, and then recompiling and reinstalling the Outlook apk.
This did trigger encryption in the subject, and html_body columns (the body column is not used) but did not encrypt the preview column in the database:
Again, please note this was just an experiment. The encryption isnot enabled in the app, and the encryption feature set may be incomplete. We hope the encryption mechanism scaffolding we see here can be modified and included in a future release.

Vendor Coordination

Microsoft Security Response Center was notified via encrypted email of these observed behaviors on December 3rd, 2013. The key message in the response received that same day was “…users should not assume data is encrypted by default in any application or operating system unless an explicit promise to that effect has been made.” On May 15th 2014 we contacted Microsoft asking for reconsideration of our report and mentioning our plans to publish this research. They re-stated their position: users of the app should not expect encryption of transmitted or stored messages.

Version Information

Our original research was conducted on the following app version below.

  • Application Label:
  • Process Name: com.outlook.Z7:client
  • Version:
  • APK(s):
  • com.outlook.Z7-1.apk (SHA1- 14b76363ebe96954151965676cfc15761650ef7e)
  • com.outlook.Z7-2.apk (SHA1- 41339b21ba5aac7030a9553ee7f341ff6f0a6cf2)

We also confirmed that the relevant classes have not changed by doing a hash comparison of the classes in latest app version which was released May 6th 2014 (

  • Version:
  • Build Number: 28.49.5701.3
  • Build Date: 2014-05-04
  • com.outlook.Z7-1.apk (SHA1 4ee3dc145f199357540a14e0f2ea7b8eb346401e)

3 thoughts on “Mobile App Data Privacy – the Example”

Leave a Reply