An article I did on our Fortify On Demand Blog (cross-posted):
Here at Fortify On Demand our engineers assess countless mobile apps. Being on both sides of the fence (static analysis and blackbox pentesting) we like to think we have a very holistic view of mobile vulnerabilities. This series is an educational resource for mobile app developers and testers exploring the newly minted OWASP Mobile Top 10 project, its categories, and how these vulnerabilities manifest themselves. We will explore the threats surrounding these vulnerabilities and in some cases look at insecure code and testing methods associated with them as well.
** Caveat: If I use examples in iOS here too often, forgive me, it’s my primary research area 😉 **
The Open Web Application Security Project (OWASP) has been categorizing, evangelizing, and publishing remediation information for web application security for 12 years. In 2007 OWASP released a project to categorize the 10 most prevalent web application vulnerabilities in order to educate developers and testers as to their manifestations and risks. The end goal being that they could be identified and reduced in web applications all over the world. The “OWASP Top Ten” project was a huge success.
In early 2012 OWASP realized that the application landscape had shifted. They enlisted the help of researchers to draft a Top Ten list for mobile applications. As seen by the graphic below:
M1: Insecure Data Storage
M1, insecure data storage, is the top plague of mobile applications. In fact, in this past year, nearly every major Alexa ranked site with a mobile application was guilty of it. The title says it all, insecure storage of data. Client-side data storage is an area where some development teams assume that users will not have access. To the contrary, many of the most publicized mobile application security incidents have been caused by insecure or unnecessary client-side data storage. Devices file systems are no longer a sandboxed environment where you cannot expect a malicious user to be inspecting. Rooting or jailbreaking a device usually circumvents any protections and in some cases, where data is not protected properly, all that is needed to view application data is to hook the phone up to a computer and use some specialized tools.
It’s important to distinguish what data is at risk and where is it insecurely stored:
- Authentication tokens or passwords
- Location data
- Stored application logs or Debug information
- Cached application messages or transaction history
- UDID or EMEI
- Personal Information (DoB, Address, Social, etc)
- Device Name, Network Connection Name, private API calls for high user roles
- Credit Card Data or Account Data
Places it can be insecurely stored:
- SQLite databases
- Log Files
- Plist Files
- XML Data Stores or Manifest Files
- Binary data stores
- Cookie stores
- SD Card
- In the cloud
The threat with M1 is often underplayed or misunderstood. In the most innocuous of threat situations you are considering lost or stolen devices. If your mobile application deals with data that is considered to be severely classified, then one important users phone being stolen is reason enough to worry. Think of all the security snafus in the past year where one stolen or lost laptop with super-secret data was a big deal.
Now, consider this, what if all at once all users of your mobile application lost their data? This is also a very possible situation.
The public is aware of the hacking and jailbreaking communities out there as a hobby but fail to realize that these “unlocking” enthusiasts are using the same type of computer exploits we have seen for years. In the case of an exploit that can be delivered remotely (like through a web browser) a mobile device can be compromised by just viewing a website. This was the case with the easiest of all Apple jailbreaks, jailbreakme.com. Now, the creators of that site were benevolent and made the exploit visible to the end user but, weaponizing the vulnerability and making it invisible to the end user is totally possible. Should another jailbreak like that come out tomorrow, and the agent delivering it was malevolent, you could have millions of phone’s data compromised. In that event, if you have followed best practices and are not storing sensitive pieces of data on the phone, you have some level of protection.
But the PIN/Passcode protects my data!
In the case above, the API’s usually used to protect data will not help you; your device has already been unlocked. In the case of a lost or stolen device, a 4 digit PIN takes 20 minutes to bruteforce. In some cases, on Android, specific implementations for the Passcode screen could be bypassed altogether! Also it bears asking, are you honestly calling the security API’s for your SQLite files and Plists? If not then the device can be locked and the data still stolen.
As for the case of “in the cloud” apps or syncing, M1 applies as well, but the Mobile Top 10 draft currently in existence doesn’t clearly state how OWASP lumped in Privacy data leakage into M1. At Fortify On Demand we see about 90% of commercial apps leverage ad or analytics libraries in insecure ways. In the best case scenario they send geolocation and innocuous personal information, but in the worst case scenario, passwords and full key presses are sent with no notification to the user.
A Visual Example:
Here we have iGoat, a purposefully vulnerable mobile app for security conscious folk to see these types of vulnerabilities first hand. In the exercise we enter our credentials, and log in to the fake bank app. We can then navigate to the file system and in our applications directory we can see a database called “credentials.sqlite”. Exploring this database reveals our username and credentials (Jason:pleasedontstoremebro!) being stored in plain text.
Manifestation on Android:
1) On android (as well as iOS) a main storage component is a SQLite database. By default SQLite does not support encryption. It can be wrapped in third party encryption with things like SQLCipher, but even these are fallible (encryption keys can be reverse engineered out of memory). In our experience these databases contain application credentials.
2) SD Card storage: We have seen a ton of apps store logs, or databases on the SD card… which is world readable and not protected.
3) Binary Data stores are another common format for developers to try and hide application data or credentials. In most cases during testing we can identify writes to a file like this often, and then we set our sights on reversing out its format. This is usually trivial.
4) Manifest or XML Files: We have seen manifest or xml files be used for storage, sometimes with credentials… very similar to plist files on iOS.
5) Browser cookie Stores: We have seen “secure” mobile applications rely on a web session, but then neglect that their web cookie is stored by the mobile OS browser. In the case where these sessions are indefinite (most mobile apps are) this is bad.
6) Any data marked with the shared preferences MODE_WORLD_READABLE will be available to any other application.
Manifestation on iOS:
1) Plist Files: just like manifest files on Droid, these are just test XML storage mechanisms often used to store application preferences. Unfortunately they also often used to store credentials.
2) SQLite Databases: Both platforms use SQLite as mentioned before.
3) Cookies.binarycookies: the default place for web cookies/session data instantiated with webkit. Also not encrypted.
4) Binary Data stores: Again, binary data blobs are often stored in the application directory. We see a lot of paid applications actually house “unlockable” content in these blobs. Too bad you can reverse out the data!
Testing for the Vulnerabilities:
As a QA or Penetration Tester, in most cases, you will see M1 issues easily and often. Simply browse your rooted or jailbroken device for these filetypes. If you have source code, recursive grep and strings can even do wonders in identifying keywords that deal with planting data into files like these (SQL Statements like insert ,etc, etc). In some cases you will need tools to convert or read the file formats. Installing SQLite via the command line is simple enough, other tools like putil will allow for conversion of a binary plist file to a readable XML one. Remember that if you see garbage from an iOS app inside one of these filetypes, you need to decrypt the app using GDB (clutch or poedcrackmod from Hackulous works well). Also, iExplorer is worth mentioning as our favorite non-jailbroken file browser.
The cardinal rule of mobile apps is: don’t store data unless absolutely necessary. As a developer you have to assume that the data is forfeit as soon as it touches the phone. You also have to consider the implications of losing every single mobile users data to a silent jailbreak or root exploit.
If the usability versus security tradeoff is too much for you, we recommend scrutinizing your platforms data security API’s and making sure you’re calling them appropriately. The lesson here is to know what data is being stored and protect it appropriately.
iOS Specific Best Practices:
- Never store credentials on the phone file system. Force the user to authenticate using a standard web or API login scheme (over HTTPS) to the application upon each opening and ensure session timeouts are set at the bare minimum to meet the user experience requirements.
- Where storage or caching of information is necessary consider using a standard iOS encryption library such as CommonCrypto
- If the data is small, using the provided apple keychain API is recommended but, once a phone is jailbroken or exploited the keychain can be easily read. This is in addition to the threat of a bruteforce on the devices PIN, which as stated above is trivial in some cases.
- For databases consider using SQLcipher for Sqlite data encryption
- For items stored in the keychain leverage the most secure API designation, kSecAttrAccessibleWhenUnlocked (now the default in iOS 5) and for enterprise managed mobile devices ensure a strong PIN is forced, alphanumeric, larger than 4 characters.
- For larger or more general types of consumer-grade data, Apple’s File Protection mechanism can safely be used (see NSData Class Reference for protection options).
- Avoid using NSUserDefaults to store senstitve pieces of information
- Be aware that all data/entities using NSManagedObects will be stored in an unencrypted database file.
Android Specific Best Practices:
- For local storage the enterprise android device administration API can be used to force encryption to local file-stores using “setStorageEncryption”
- For SD Card Storage some security can be achieved via the ‘javax.crypto’ library. You have a few options, but an easy one is simply to encrypt any plain text data with a master password and AES 128.
- Ensure any shared preferences properties are NOT MODE_WORLD_READABLE unless explicitly required for information sharing between apps.
In this write-up we have explored M1 Insecure data storage in several contexts. Hopefully this information leads to more secure mobile apps. In January we will continue on down the Mobile Top 10, and look at M2, Weak Server Side Controls.
If you would like more information on assessing your mobile apps, we recommend our easy to use cloud offering, Fortify On Demand. In this process your mobile apps are assessed statically and dynamically by our word class software and engineers. To schedule a “proof of value” free assessment, contact [email protected] and for technical comments or questions I can be reached at Jason.haddix –a.t- hp.com.
References and Resources:
- OWASP Top 10 Mobile Risks Page
- OWASP IOS Developer Cheat Sheet
- Google Androids Developer Security Topics 1
- Google Androids Developer Security Topics 2
- Apple’s Introduction to Secure Coding