Do you think your app is safe enough? Nothing could be further from the truth!
Nowadays we are surrounded by mobile applications which influence almost every aspect of our everyday life. Due to the fact that mobile apps also touch some sensitive parts of our lives, namely: banking, shopping, medical care, contacts, etc., developers put huge efforts into expanding their security. App creators implement more and more advanced data protection mechanisms, but do they really remember about securing less obvious elements that take part in data processing? In this article we would like you to show how to avoid data leaks related to these elements based on Android OS.
Data processing is a particularly sensitive part of mobile application logic. It is essential to provide speed of processing and availability of data. On the other hand, data may contain sensitive information that need to be secured. This compromise is a frequent source of potential leaks of data. How? It is obvious that sensitive data should be encrypted, but to encrypt any kind of data we need to use encryption keys. Such keys should be provided to the application. A frequent error that causes data leaks is that encryption keys are saved on the device. This is very problematic, as such keys are very often saved in plain text form. This is unacceptable because in fact it makes all the encryption efforts pointless. If the attacker comes into possession of such an encrypted database then it is enough to take the public key and decrypt the db. This is so easy that you can do it using publicly available online tools.
In order for encryption keys to be handled safely developers should use a set of Android data encryption tools called KeyStore. It is designed for handling and storing encryption keys with most common and secure algorithms used all over the world. This tool is part of Android security tools, integrated with the system to provide the best performance and increase data processing speed. Make sure that all your encryption keys are handled in a correct way using KeyStore. This makes your Android data encryption mechanism complete!
The most commonly used protocol for transferring data between mobile applications and a server is HTTP. The data sent with this protocol is not encrypted, for security purposes there is also an encrypted version of HTTP called HTTPs. It is based on TLS / SSL asymmetric cryptography.
Using HTTPs as a safe method of communication is quite a common practice and it provides a fairly high level of security. Naturally, in order for the connections to be secure the HTTPs protocol should be implemented correctly. Unfortunately, this is not so obvious and quite often it is implemented without accurate care.
In short, to encrypt communication using HTTPs the server needs to be able to handle HTTPs connections. When this condition is applied then a client needs to send request to the address which starts with “https” protocol. Under the hood (on lower levels) the server and client establish parameters of the encryption in process that is called handshake. If handshake is done correctly all communication is encrypted.
The problem is that the content of this encryption can be decrypted in the case of a man-in-the-middle attack in which a node (program or device) is placed between the application and the server. This node decrypts the connection in the same way as the application and re-encrypts it again but in the meantime it reads the contents. Because of this, neither the application, the server nor the user are aware of the communication. To prevent this, the encrypted version of HTTP needs to be implemented fully. A developer needs to add certificate pinning inside the application code. This consists of adding a signature of the certificate server to the application code in such a way that the application is able to verify the server certificate. Then the application will only receive responses from one server with a certain certificate so it will not be possible to decipher the communication because the client application immediately rejects the connection due to the bad signature of the certificate.
This certificate pinning method is not only a part of Android security mechanisms but it should be also implemented on each client app which is responsible for encrypted communication using HTTPs connection. Without that it is quite easy to break this data encryption. So remember to verify if your HTTPs is implemented correctly.
All data and business logic is based on system components included in the Android SDK. It’s not obvious for everyone that these elements require additional protection. Special protection needs, in particular, these elements of applications, which constitute the so-called IPC (Inter-Process Communication ) endpoints. This means that those endpoints are used for sending and receiving data between different processes: of the same application, other applications or systems components. The most common way to handle such communication is to send informations as broadcasts.
Broadcast is a message that is sent by the application to the receivers through the system. Each broadcast should be sent with a set of data of specific event. This set is called Intent. Such broadcast is sent to the system using Android SDK and is handled by the OS. Then the OS sends such broadcast to all applications, services and processes, which are registered for this kind of event. The mechanism which allows such registration is called Intent Filter. It is a very simple Android data protection mechanism which allows for reduction of the number of applications that can receive the specific broadcast.
Implementation of Intent filter is very simple. It only consists of an indication of an Intent scheme (e.g. its actions and categories) and it points the element of the app that should opened when such Intent is received. As you can see the mechanism is very simple, so you can imagine that it is also very simple to insert same Intent filter in a hostile application and then gather all of the data that that was sent inside the broadcast.
Imagine the following situation: your app has a Service that is responsible for sending and receiving real-time messages from a server. This service is running in different processes to prevent blocking the app UI. Communication between the proper part of the app and the service is handled by the broadcasts. So it's easy to see that all important information your app gets from the server through the Service can easily be scrambled by another application. The only condition is that this application needs to have a correct Intent filter definition. Of course there is protection mechanism that can be used for this. To protect the app from such problem, a developer needs to use the Android security mechanism known as Permissions. Most common usage of the permission system is to access system or device resources like e.g. GPS, Bluetooth, etc. In addition, developers can create their own, custom permissions. Custom permissions allows to restrict access to some application components. To make this limitation possible, remember to define a custom permission with the correct protection level and assign permission to the app element (e.g. Activity, BroadcastReceiver, etc).
An example of such protection level is “signatureOrSystem” which means that component with such permission could be used only by the application with the same signature or by the system. There are also more levels of protection designed for different purposes. So a small improvement like custom permissions can significantly increase the Android app security. Please check if your development team has already implemented these security measures inside of your application.
The problem with data caching is very often overlooked, not only by app users but also by programmers. You often hear that someone pastes their password into the place of the login, or even worse, sends it in a private message. How is that possible? Is there a way to avoid this type of user error? Of course there is!
The problem arises from the work of the so-called mechanisms of user data caching. Their purpose is to make life easier for the user. Examples of this type of mechanisms are the user’s dictionaries, which are responsible for suggesting words based on words used earlier by the user. This ensures the user's comfort and increases efficiency.
Another type of this kind of component is the Clipboard which allows to transfer data between applications by saving it temporarily in the the system memory. Due to the fact that all these elements are very helpful to the user, developers often use these mechanisms in their applications to improve User Experience. But this process involves some risk. Because this mechanism works quite automatically, it saves all the information without knowing its context. Therefore, passwords or other sensitive data can leak to the clipboard or keyboard dictionary!
How can it happen? Well, it is really simple. Let’s imagine such a situation - the user enters a password to log in to the application, the password is saved by the keyboard cache. The user goes to another application, e.g. a web browser to search for information such as a favorite sport team. The keyboard prompts him with a password and replaces the typed phrase with the password (because it was very similar), the user does not notice it and clicks ok. The password spread throughout the Internet as a searched phrase, namely in: search logs, caching algorithms, or as a search result etc. In addition, it is immediately associated with a specific user because, for example, Google's Android browser is instantly integrated with Gmail. The illustrated example is one of many directions in which a password or other confidential information may leak as a result of the caching mechanism.
Sensitive data, such as passwords, can be cached by the application via the text fields. Text fields in Android may have different input types, and they are configurable by the developers. Most of text field types such as "text", "email" "webAddress" indicate how the keyboard should behave with regards to the data typed in the given field. In our case, it is responsible for turning the user's caching mechanism and user dictionaries on/off. To disable this function for a given field, it is necessary to set the appropriate input type that will block these functions, such as one of the "password" types. Not only will this block auto-caching, but it will also prevent from copying the input to the clipboard.
It is a seemingly obvious thing but is it really? In many cases, it may turn out that it is not so obvious for many reasons. Sometimes it is because of a badly designed application, sometimes it is easier for the developer to use “text” input and style it than to use the “password” input type because it has limited styling and management capabilities. Sometimes this is caused by poorly defined requirements, for example when a customer requires everything to be copied everywhere. And sometimes this is just a mishap. So make sure that your application uses correct input types for sensitive data. It is more important to protect users and their sensitive data than to maintain perfect User Experience or design of some inputs fields.
Other very important elements in the process of developing applications are logs. Logs are especially useful for developers while analyzing the work of algorithms responsible for data processing inside apps. Adding data to logs makes it easy for the developer to make sure the results are correct or the sequence of processing is performed in the correct order. Unfortunately, as a result of that, logs may also store sensitive data like e.g. passwords or access to keys/tokens. It is dangerous, because logs are stored locally on devices. Moreover, on any device with a OS version lower than Android 4.2, logs are publicly readable and visible to all applications installed on device. Only since Android 4.2, the access has been limited to the certain applications. So, how can we secure that? The best practice and advice is very simple. Make sure that your application does not use logs at all. Of course logs are very useful but your developers don’t need it on the production version of your app, right? So make sure your developers disable logging tools for the production version of your product.
The article shows a couple of places where user data can leak. You can use our advice to add another Android security layers in order to make your app more tight. Of course there could be more places like this, so you should remember that there is always room for new improvements that increase the safety of your data. Just remember to be sure that your team knows all the possible problems and is able to implement all possible means of data protection to solve the problems and reduce risk of leaks.