Introduction
When developing a mobile application, you should take into account that the data that this application operates on may be of some interest to third parties. The degree of value of this data varies widely, however, even the most simple private information, for example, an application login password, requires elaboration of its protection. This is especially important in light of the spread of Mobile application development services to all areas of electronic services, including financial and banking transactions, storage and transmission of personal data, and so on. Anyone interested – welcome to Cat.
All of the following is solely my experience; of course, the data may be inaccurate, so I will be grateful for any corrections and additions to the article. I did not find comprehensive articles on the Internet on similar topics that would collect all the necessary (at least basic) information in one place, so I decided to summarize my experience in this area at the current time.
Mobile application protection
Main types of attacks on mobile applications:
- Decompiles the application file (.ipa files for Apple iOS and .apk files for Google Android) and parses locally stored data. The protection of this, currently most important, level lies entirely on the shoulders of the mobile developer.
- Interception of data transmitted over the network (MITM attacks). Most mobile applications are client-server, and therefore constantly transmit and receive large amounts of information. And although modern mobile and web development is actively completing the transition to the HTTPS communication protocol, nevertheless, you should not rely on the only line of defence in the form of a secure communication channel.
- Rooting the device and attacking the application and the algorithms used in it through external debugging tools.
List of main application vulnerabilities
Let’s consider vulnerabilities of a general nature, without reference to a specific platform. Hereinafter, the abbreviation KVD is used – critical user data. KVD includes any data that should not be available to a third party, this applies to both the user’s personal data (date of birth, residential address, personal correspondence) and his private data (passwords, credit card data, bank account numbers, order numbers etc).
The list of main vulnerabilities is as follows:
Using unprotected local storage.
- Danger: Very high.
- Comment: It is found everywhere and is expressed in the storage of KVD in unprotected or weakly protected local storage, specific to a particular platform. Third-party attacks is simple and usually do not require special skills from the attacker.
- Protection: KVD can only be stored in secure platform storage facilities.
Storing KVD in code.
- Danger: High.
- Comment: The vulnerability concerns the storage of VDCs inside the code (in static constant strings, in application resources, etc.). Prominent examples: storing a password salt in a constant or macro, which is used throughout the code to encrypt passwords; storing a private key for asymmetric algorithms; storing passwords and logins for server nodes or databases. Easily decompiled by a third party with basic decompilation skills.
- Protection: Do not store any KVD in application code or resources.
Application of algorithms with private key storage.
- Danger: High.
- Comment: The vulnerability is relevant if the private information of the algorithm (private key) is forced to be stored in the code or resources of the mobile application (most often this happens). Easily opened by decompilation.
- Security: In mobile development, it is advisable to use only modern symmetric algorithms with a generated random one-time key that are highly resistant to brute force hacking, to remove the asymmetric private key outside the application, or to personalize this key (for example, the private key can be a user login code, stored encrypted in a secure operating system storage).
Using an asymmetric algorithm with a private key known to the server.
- Danger: Depends on the security level of the server.
- Comment: The vulnerability is twofold. Storing the private key allows for the possibility of decrypting user data on the server side. Firstly, this is incorrect from a security point of view (if the server is hacked, the attacker will also gain access to the users’ private data), and secondly, it violates the privacy of personal data. The user must always be sure that his personal information is not known to anyone except himself (unless he has explicitly given permission for its publication). Often applications position themselves as secure, but in reality, they are not, since they contain tools for decrypting personal information.
- Security: Without explicit need and explicit permission from the user (most often through a license agreement), neither the application nor the server should have any ability to decrypt the user’s private data. The simplest example is that the user’s password should go to the server in the form of a hash, and the hash should be checked, not the original password (the server has absolutely no need to know the user’s password; if the user has forgotten it, for such a situation there is a long-established password recovery mechanism, including with two-factor client authentication for increased security of the recovery procedure).
Use of self-written encryption and security algorithms.
- Danger: Medium.
- Comment: This is a direct violation of the Kerkhoff principle. It is expressed in the developer’s attempt to invent “his own personal, unknown to anyone, and therefore super-secure encryption algorithm.” Any deviation from existing, repeatedly tested and studied, mathematically proven encryption algorithms in 99% of cases results in a quick hack of such “protection”. Requires the attacker to have medium-high skills.
- Security: A suitable algorithm should be selected only from well-established and up-to-date well-known cryptographic algorithms.
Transmission of pressure build-up to the external environment in an open form.
- Danger: Medium.
- Comment: Expressed in the transmission of data transfer data without the use of encryption via any available communication channel with the external environment, be it data transfer to a third-party application or transfer to the network. It can be opened indirectly by opening not the application, but its storage, or the target application. Hacking requires the attacker’s skills, provided that the storage is secure.
- Security: Any KVD must be encrypted before leaving the application. Local platform storage is not an application area; they should also receive only encrypted data as input.
Ignoring the fact of the presence of rooted or infected devices.
- Danger: Medium.
- Comment: Rooted devices are devices that have been modified to obtain superuser rights for any operations initially prohibited by the operating system manufacturer. Performed by the user on his device independently, and not necessarily voluntarily (the client may not be aware that the device is hacked). Installing the application on a rooted device eliminates all standard security measures of the operating system.
- Protection: If this is technically possible for the platform, then it is advisable to prohibit the operation of the application if it is possible to understand that it is being launched on a rooted device, or at least warn the user about this (thanks for the addition DjPhoeniX ).
Storing KVD in protected storage facilities, but in open form.
- Danger: Medium.
- Comment: Developers often tend to save KVD in secure system storage without additional protection, since the system mechanisms are highly resistant to hacking. However, their level of resistance drops to a minimum if the device is rooted.
- Security: KVD should not be used in an application without additional encryption. As soon as there is no longer a need for “open” KVDs, they must immediately be either encrypted or destroyed.
Translation of some functionality into built-in web engines.
- Danger: Medium.
- Comment: Most often it looks like transferring the KVD to the built-in browser, where an external web page is loaded, performing its part of the functionality. The level of protection in this case is sharply reduced, especially for rooted devices.
- Protection: Do not use the built-in browser and built-in web engine in operations with KVD. As a last resort, encrypt the KVD before transmission.
Reverse engineering of algorithms of intellectual value.
- Risk: Low, depends on the value of the algorithm.
- Comment: If, when developing an application within a company, certain proprietary algorithms are used that may be of high value to potential competitors or hackers, then these algorithms must be protected from unauthorized access.
- Protection: Automatic or manual code obfuscation.
Specifics of mobile application development
There are several points common to all mobile platforms that should be observed during development.
Custom code protection
- If an application is protected by a user password (PIN code, fingerprint scan, picture password, etc.), then when the application goes into the background (“minimized”) it should immediately display a window for entering this security code, covering the entire application screen. This eliminates the possibility for an attacker to obtain private information if the device is stolen while the application is still running and in sleep mode.
- Any user code should have a limited number of input attempts (for example, 5 times), then, in case of failure, the application should be automatically logged out (or completely blocked, depending on the specific application).
- Currently, when using digital codes, it is strictly recommended to use a code length limit of at least 6 digits (more is possible, less is not allowed).
Functioning of a client-server application
- For client-server applications, it is very useful to use a session mechanism with a limited session lifetime. This will avoid the application being idle in unprotected mode if the user simply forgot to close it and left the device in free access. It should be taken into account that the session validity period and its identifier relate to the KVD, with all the ensuing consequences. One of the successful examples of implementing such a mechanism is obtaining the absolute time value from the server after completing the user authorization procedure (the date and time should indicate exactly when the session will become inactive). The session expiration date and time should not be generated on the device; this reduces the security and flexibility of the application.
- The client-server application should not change the KVD in local mode. Any action that requires changing the KVD must be synchronized with the server. The only exception to this rule is a custom login code, which is specified personally by the user and stored in secure local storage.
Working with dates
- When dealing with dates that are important for the operation of the application, such as the time the session was destroyed, you should not rely on relative time. That is, the data transmitted from the server should not contain a date in the form “plus N seconds/hours/days from the current moment.” Due to the presence of potentially high delays in data transmission over the network from the mobile application development services to the server and back, such a synchronization method will have too large an error. In addition, an attacker (or simply an unscrupulous user) can simply change the local zone on the device, thus violating the logic of the application’s restrictive mechanisms. You should always transmit only the absolute time value.
- Absolute values should be transmitted using universal methods for exchanging such information, without being tied to the time zone of a specific user device. Most often, the best option is for the application to behave in such a way that the data is displayed to the user in his local time zone, but is stored and transmitted in a format that is not tied to a time zone. Suitable formats for dates and times are either a universal UNIX timestamp stored in a 64-bit signed integer variable (UNIX timestamp is the number of seconds that have passed since January 1, 1970) or, as a last resort, a string in full ISO-8601 format with zero time zone. The UNIX timestamp is preferable; it avoids potential errors and problems with converting strings to dates and back on different mobile platforms.
Additional recommendations
- The application should not display private user information in large, bright, easily readable fonts, unless clearly necessary and without a separate request from the user, in order to exclude the possibility of reading this data from afar from the device screen.
- You should not blindly trust open-source libraries that offer some protection to users’ private data. The exception is libraries that are time-tested and used in large corporate projects (for example, built-in encryption in the open Realm database engine). In the vast majority of cases, standard operating system protection mechanisms and publicly available proven cryptographic algorithms will be more than sufficient.
- It is absolutely unacceptable to use closed-source cryptographic libraries (even if they are paid). In such solutions, you will not be able to check how effective a given library is, as well as how “honest” its protection is (whether there is a backdoor mechanism, or whether “protected” data is sent to some third party).
- In a release, builds of applications, logging of data to the system console and unprotected files should be disabled. Specific logs for developers may be present, but preferably in encrypted form, in order to prevent third parties from accessing sensitive proprietary information that may be present in the logs.
iOS platform-specific information
Let’s look at the data storage available to the developer when developing for iOS:
NSUserDefaults.
- Standard security: Absent.
- Comment: Used only to store data that is safe for the operation of the application and not related to private information. Most often, only client interface settings are written there. This storage is not suitable for other data, since it is a regular file and can be opened in a few seconds.
Binary files (NSKeyedArchiver).
- Standard security: Average, if you use the attribute NSFileProtectionCompleteby key NSFileProtectionKey, otherwise – absent (thanks for the addition agee ).
- Comment: They themselves are physical files and can be easily accessed by a third party. The level of protection depends solely on the encryption algorithms applied to the data. This is not the most convenient place to store data, so unless absolutely necessary (most often it is the ability to transfer this data, for example, by email), it is better not to use this method. If a file is created with an attribute value NSFileProtectionCompletefor the key NSFileProtectionKey, then the operating system keeps the file in an encrypted state while the device is locked or in a booting state, but if these conditions are not met, the data will be readable and writable as in a regular file, so this is only a temporary measure with a narrow scope.
Database.
- Standard security: Depends on the engine and developer.
- Comment: Modern database engines support internal data encryption. The developer will need to find a balance between encryption and performance, enable database encryption for critical data, and also additionally apply encryption for data storage before writing to the database.
Keychain.
- Standard security: Maximum ( does not apply to jailbroken devices).
- Comment: The most suitable place for storing any HPC. However, given that the device may be rooted, all KVDs must be additionally encrypted before being saved to Keychain. Additionally, you should use cloud synchronization with caution due to the ability to automatically save Keychain to the cloud. In case your application uses CloudKit, you need to be careful about the data that should not be synced (if any) and exclude it from the set of copied data.
Android platform-specific information
I have little knowledge of the Android platform, so the list below is a brief summary of the basic materials that I was able to find on this platform:
- The most successful option for a user code is a graphic code, digital (6 digits or more) is an additional option.
- Requesting permissions for certain types of application activity is mandatory and must be done explicitly for the user with an explanation of what exactly the permission will be used for. You need to request specific permission only if there is a direct need for its use; also, the request for permission must be shown exactly at the moment when it was needed, not earlier. Additionally, if the target Android SDK version is 23 (or later), then you should only request permissions through the Compatibility Permissions System.
- The HTTP client must be configured to force the use of a secure communication channel (HTTPS).
- In the release build of the application, all debugging functions should be disabled, for example, the option debuggable must be disabled to prevent an external debugging application from connecting to the program.
- On application screens where private user information is located, it would be useful to force a ban on programmatically creating screenshots of the application window, as well as disabling the display of screenshots in the task manager.
- Any private information can be additionally preceded by a request for the user’s personal key specified by him to enter the application (if any).
- Inside the application code for resolving paths, it is recommended to use getCanonicalPathinsteadgetAbsolutePath.
- Open components used in the application (for example, Service or Content Provider) must be closed using a flag exported = false in the application manifest (Android Manifest). This will prevent access to these components from another application.
In addition, you need to use the available information stores with caution:
Shared Preferences.
- Standard security: Absent.
- Comment: Should only be used for its intended purpose, namely to store publicly available, unprotected user settings. Other data should not be posted here.
Databases (SQLite).
- Standard security: Depends on the developer.
- Comment: These are ordinary files, so all KVDs must be appropriately encrypted before recording. The database allows for automatic encryption; enabling it will be a good way to enhance data protection. As an encryption key, it is most advisable to use a security code specified personally by the application user (the code, in turn, must be encrypted and saved in the Account Manager, see description below).
Account Manager.
- Standard security: High (only up to API version 18).
- Comment: All KVD should be placed here, but additional data encryption must be performed first. After API 18, use is not recommended.
KeyStore.
- Standard security: Maximum ( does not apply to rooted devices, available with API 18).
- Comment: Similar to Account Manager, but it is strongly recommended to use this storage instead if KeyStore is available to the developer (API v.18, Android 4.3 and later).
Conclusion
It’s also worth mentioning that the number of protection levels applied depends on the specific application. For example, if the application is not client-server at all, does not contain any KVD, and does not operate with valuable internal algorithms, then there is no point in attaching any protection to it at all. If the application is focused, for example, on performing banking operations or storing user passwords, then the degree of its security should be the highest. However, the common vulnerabilities in the mobile app development services sector listed earlier can be excluded from the application quite easily, most often without introducing any special additional costs if the application of the required level of protection was started in the early stages of application development. However, introducing post-facto protection into an already running application may well involve significant expenditures of effort and time for developers. Therefore, the selection and approval of the level of security, as well as the list of pressure indicators in the application being developed, must be carried out at the earliest stages of design.