Security Practices for Mobile App Developers

tom-hartz - May 18 '20 - - Dev Community

A lot of my time writing software is spent concerned about things other than security. From the companies and projects I've seen, security usually ends up being either completely forgotten, or prioritized behind all the other important things like functionality, UX, test coverage, and performance. Managers and other stakeholders usually are motivated to spend just enough time and money on a project so that it is functional in the form of a minimum viable product. Security is often not a concern for them, until it is too late!

As developers then, it is our ethical responsibility to ensure we follow best practices and keep security in the forefront of our minds. As craftsmen we must strive for the applications and tools that we create to be robust and impenetrable to outside intruders. Architects should be thinking about this often, but ideally even junior level developers should be aware of the basic best practices and techniques. It seems prudent to talk about some of the security concerns around mobile application development.

Perhaps most obvious is that you should secure all API communications with SSL encryption. It's generally best to just use HTTPS to transmit all data between devices and servers, but especially sensitive data. Sensitive data includes Personally Identifiable Information (PII), your user's password, user activity, company trade secrets, etc. There can be exceptions to this of course. If the data is not sensitive, or if the communication is only occurring on internal private networks, then maybe you don't need to encrypt it. But it's not hard to use SSL. Keep in mind, SSL alone does not make your application data 100% safe. Attackers have many other means to steal data, so packet encryption on the network is just the first step. Also, if you've heard of Heartbleed, you know that even widely used SSL implementations can sometimes be faulty. But flatly, its 2018 people, secure your friggin' endpoints!

Sensitive data should be encrypted "in-motion" (on the network through SSL secured APIs) and "at rest" (when stored in a database on a server or on a phone). Local storage is a very common feature in mobile apps, and data should be encrypted here as well. The only time sensitive data should ever be unencrypted, is temporarily in RAM, and on a screen displayed to an authorized user. Encrypting local storage is a security practice that makes sure a compromised device does not make application data readily available to a thief.

A handy way to store small bits of information securely in an app is with the device Keychain (iOS/Android). Keychain frameworks provided by Apple and Google essentially guard data so that it can only be accessed by the registered application at runtime. Now, there are older OS versions and jailbreaks out there where it possible to decrypt and read this application data, so you should always consider the tradeoffs and only store data on device when it is absolutely necessary. Is it really important that the user have access to this data offline? Can it be stored on the server and accessed via secure communication instead?

If you need to store more than a handful of secrets, you probably are using a more performant local storage option such as SQLite. This can also be encrypted! One approach is to encrypt/decrypt individual data fields on their way into and out of the data access layer of your application. However this is a bit cumbersome and more processing intensive than simply encrypting the entire database file, which your app can then decrypt into memory just once when it starts (the SQLite file will still be encrypted in the file system). DO NOT hardcode the encryption key(s) into your source code! I wouldn't trust putting keys into a private repo either (Github has been hacked before). Ideally, each app instance should have a unique encryption key. You can store the encryption keys in the Keychain, or fetch them from an API. The latter implies that users would have to be online to do an initial login, then can go offline as long they don't fully quit the app. Encrypting data this way can make it frustrating or impossible for an attacker to access when a phone gets lost or stolen.

When a device is known to have been lost or stolen, it is good to have a contingency plan. A remote wipe is possible from the OS, and also something that you can custom build into your app (push notifications can trigger background process to start). However you should also consider that the user might not be immediately aware that they lost their phone. For this reason you should make logins expire as reasonably quickly as possible. Personally, I never want to let a login last for more than a day. But again there is a trade off here of security vs. usability, and no one likes having to login over and over again. Side note, two factor authentication through SMS becomes quite useless when the attacker is literally holding the user's phone. To that end, I don't think SMS auth adds any protection at all for mobile apps, and I have a laugh whenever an app texts me a code on the device I am logging in from.

Another concern for mobile apps in particular is code security. Typically mobile apps are deployed via app stores, and available for download by anyone in the world. Maybe your app requires a login to do anything, so you don't care if unauthenticated users install and run it. However, you should consider what a malicious "black hat" attacker can do with your app bundle. As an attacker, I can take your apk or ipa file, unzip it, and start inspecting the bundle contents for vulnerabilities. I might attempt to decompile and reverse engineer your binary code files. I could also deminify and tamper with your hybrid app javascript code. Doing so means I could read any hard coded secrets or endpoints, or "fake" a login to move past that screen. This is where "security by obscurity" fails, and why it's so important to have proper encryption setup to protect your data and endpoints.

DISCLAIMER: Black hat practices are not something I have a lot of experience with, and I'm writing this section hypothetically as if I were a malicious agent, for the sake of argument and fun. I would never attempt this on someone else's compiled application! ✌️😊

When writing your application code, consider it vulnerable. Always strive to Keep It Simple, Stupid™. A popular opinion these days is the less code you have, the better. However, you should also be careful when trying to AVOID reinventing the wheel. If you are bringing in third party frameworks, do your due diligence and READ THE SOURCE CODE! If you can't view the source before baking it into your app, that is akin to taking candy from a stranger. You are putting a lot of trust in these third party strangers to give you something sweet that won't disable or kill you, or worse - attempt to steal your identity and information.

Last thing I want to touch on briefly is social engineering. This is definitely the hardest thing to protect against as a developer. We can follow all the security best practices in the world and have good encryption put in to protect our apps, but when a user gets scammed and leaks a password, all bets are off. Once an attacker has valid credentials, they are freely able to use the app as if they were someone else.

For internal business productivity apps, it is really important then to design good authorization mechanisms. Make sure you understand the difference between authentication and authorization, and make sure you're doing both right. You should meticulously discriminate on who can see what data. Make sure employees only have access to data that they need to do their job! And if you can, make sure your organization has good training and communication in place to help your users recognize and avoid social engineering scams.

For all you other mobile devs out there, I hope you learned nothing from this article, and rather that it reinforced some obvious things you already knew. It is all too easy to let security get swept under the rug on a project, and I've certainly been guilty in the past of focusing on the more fun parts. Security is a big topic and an area where the industry at large needs to continually keep improving. As security practices evolve, so do hacking techniques. Put another way, as hackers get better at cracking systems, we must also change our approach to security. It is almost like a dance, or a hamster in a wheel; it is a continuous struggle to design systems where digital information is safe. As a society, we are likely going to keep seeing major scale data breaches occur. And again, as developers it is in our best interest to keep abreast of security concerns, keep security in the forefront of our minds, and design our systems as securely as possible.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .