Introduction
When developing a mobile application, it should be taken into account that the data with which this application operates 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, the password to enter the application, requires consideration of its protection. This is especially important in light of the spread of mobile applications in all areas of electronic services, including financial, banking, storage and transfer of personal data, and so on. All interested - welcome under cat.
All of the following is exclusively my experience, of course, the data may be inaccurate, so I will be grateful for any amendments and additions to the article. I did not find exhaustive articles in the network on a similar topic, which 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 app security
The main types of attacks on the mobile application:
- Decompiling the application file (.ipa-files for Apple iOS and .apk-files for Google Android) and parsing locally stored data. Protection of this most important at the present time 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, therefore, they 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 a single line of protection in the form of a secure communication channel.
- The rutting device and the attack on the application and the algorithms used in it through external debugging tools.
List of key application vulnerabilities
Consider vulnerabilities of a general nature, without reference to a specific platform. Hereafter, the acronym 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 and etc).
The list of major vulnerabilities is as follows:
Using unprotected local storage.
- Danger: Very high.
- Comment: It occurs everywhere, expressed in the storage of the ARC in unprotected or poorly protected local storage specific to a particular platform. Opening by a third party is elementary, and, as a rule, the attacker does not require special skills.
- Protection: Store KVD only in secure storage facilities of the platform.
Storage KVD in the code.
- Danger: High.
- Comment: Vulnerability concerns storage of ARCs within the code (in static constant strings, in application resources, etc.). Vivid examples: storing password salt (password salt) in a constant or macro that is used throughout the code to encrypt passwords; storing a private key for asymmetric algorithms; storage of passwords and logins for server nodes or databases. Easy to open by a third party with basic decompiling skills.
- Protection: Do not store any KVD in the code or resources of the application.
The use of algorithms with the storage of a private key.
- Danger: High.
- Comment: Vulnerability is relevant if the private information of the algorithm (private key) is forcedly stored in the code or resources of the mobile application (most often it happens). Easy to open by decompiling.
- Protection: In mobile development, it is desirable to use only modern symmetric algorithms with a generated random one-time key, which are highly durable with a brute force method, or output an asymmetric private key outside the application, or personalize this key (as an example, the user’s login code can be the private key saved in encrypted form in the secure storage of the operating system).
Using an asymmetric private key algorithm known to the server.
- Danger: Depends on the security of the server.
- Comment: Vulnerability is twofold. The storage of a private key allows the ability to decrypt user data on the server side. Firstly, it is incorrect from the point of view of security (if the server is hacked - the attacker will also get access to private user 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 (only if he explicitly did not give permission to publish it). Often, applications position themselves as protected, but in reality they are not, as they contain tools for decrypting personal information.
- Protection: Without the explicit need and explicit permission of 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 a user’s password should go to the server as a hash, and the hash should be checked, not the original password (the server has absolutely no need to know the user password; if the user forgot it, there is a long-established password recovery mechanism for this situation, including with two-factor client authorization for enhanced security recovery procedures).
Using self-written encryption and protection algorithms.
- Danger: Medium.
- Comment: This is a direct violation of the Kirkgoffs principle. It is expressed in the developer’s attempt to invent "his own personal, unknown to anyone, and therefore a super-secure encryption algorithm." In 99% of cases, any deviation from the existing, repeatedly tested and studied, mathematically proven encryption algorithms results in a quick hack of such “protection”. Requires mid-high skills from the attacker.
- Protection: You should select a suitable algorithm only from well-established and relevant well-known cryptographic algorithms.
Transfer of the ARC to the external environment in the open form.
- Danger: Medium.
- Comment: It is expressed in the transmission of ARCs without the use of encryption over any available communication channel with the external environment, be it data transmission to a third-party application or transmission to the network. It can be opened indirectly by opening not the application, but its repositories, or the target application. Hacking is demanding the presence of skills from an attacker, provided that the storage is protected.
- Protection: Any ARC should be encrypted before exiting the application. Local storage platforms are not an application area, they should also receive only encrypted data at the input.
Ignoring the fact of the presence of rooted or infected devices.
- Danger: Medium.
- Comment: Ruled devices are devices where a modification is made to obtain the superuser's rights for any operations initially prohibited by the manufacturer of the operating system. It is performed by the user on his device independently, and not necessarily voluntarily (the client may not be aware that the device has been hacked). Installing the application on the routine device eliminates all the standard means of protecting the operating system.
- Protection: If it is technically possible for the platform, then it is desirable to prohibit the operation of the application, if you manage to understand that the launch is performed on a rooted device, or at least warn the user about it (thanks for the addition of DjPhoeniX ).
Storage KVD in secure storage, but in the clear.
- Danger: Medium.
- Comment: Developers are often inclined to save KVD to secure system storage without additional protection, since the system mechanisms resist hacking well. However, the level of their resistance falls to a minimum if the device is routine.
- Protection: KVD should not be used in the application without additional encryption. As soon as the need for "open" KVD disappeared - they must immediately be either encrypted or destroyed.
Translation part of the functionality in the embedded web engines.
- Danger: Medium.
- Comment: Most often it looks like the transfer of KVD to the built-in browser, where an external web page is loaded that performs 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 the built-in web engine in operations with the ARC. In extreme cases, encrypt the ARC before transmitting.
Reversible engineering of algorithms of intellectual value.
- Danger: Low, depends on the value of the algorithm.
- Comment: If during the development of an application within the company, some proprietary algorithms are used that may be of high value to potential competitors or hackers, then these algorithms should be protected from unauthorized access.
- Protection: Automatic or manual code obfuscation.
The specifics of developing mobile applications
There are several common points for all mobile platforms that should be followed during development.
User Code Protection
- If an application is protected by a user password (PIN code, fingerprint scan, graphic password, etc.), then when the application goes into the background (“folding”), it should immediately display an input window for this security code, overlapping the entire screen of the application. This eliminates the possibility for the attacker to obtain private information in the event of theft of the device 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 particular application).
- At present, when using digital codes, it is strongly recommended to use a limit on the code length of at least 6 digits (more is possible, less is not).
The operation of the client-server application
- For client-server applications, it is very useful to use a session mechanism with a limited session lifetime. This will prevent the application from being “idle” in an unprotected mode if the user simply forgot to close it and left the device freely available. It should be noted that the duration of the session and its identifier refer to the ARC, with all the ensuing consequences. One of the successful examples of the implementation of this mechanism is to obtain the absolute value of time from the server after going through the user authorization procedure (the date and time should show exactly when the session will become inactive). The date and time of the end of the session should not be generated on the device, this reduces the security and flexibility of the application.
- The client-server application should not make changes to the ARC in local mode. Any action that requires changing the ARC should be synchronized with the server. The exception to this rule is only a user login code, which is set personally by the user and stored in secure local storage.
Work with dates
- When operating with dates important for the operation of the application, such as the time of the session destruction, you should not rely on the relative time. That is, the data transmitted from the server should not contain the date in the form of "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 to the server and back, such a synchronization method will have too much error. In addition, an attacker (or simply an unscrupulous user) can simply change the local belt on the device, thus violating the logic of the restrictive mechanisms of the application. It is always necessary to transmit only the absolute value of time.
- Absolute values ​​should be transmitted using universal methods of exchanging such information, without reference to the time zone of a specific user device. Most often, the best option is the behavior of the application, in which data is displayed to the user in its local time zone, but it is stored and transmitted in a format that is not tied to a time zone. Suitable formats for dates and times are either the universal UNIX timestamp stored in a variable of a 64-bit integer signed type (UNIX timestamp is the number of seconds since January 1, 1970), or, in extreme cases, a string in the full ISO-8601 format with zero time zone. UNIX timestamp is preferred, it allows you to avoid potential errors and problems with converting strings to date and back on different mobile platforms.
Additional recommendations
- The application should not display private user information in large, bright, well-readable fonts, without the explicit need for it and without a separate user request, in order to exclude the possibility of reading this data from a distance from the device screen.
- Do not blindly trust open source libraries that offer some kind of protection to private user data. The exceptions are libraries, time-tested and used in large projects of corporations (for example, embedded encryption in the open engine of the Realm database). In the overwhelming majority of cases, the standard mechanisms for protecting the operating system and publicly-proven cryptographic algorithms will be more than enough.
- 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 in any way how effective this library is, and also how "honest" its protection is (does it have a backdoor mechanism, or is the "protected" data not sent to any third party).
- In 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 an encrypted form, in order to avoid third-party access to proprietary information that may be present in the logs.
Consider data warehousing available to a developer when developing for iOS:
I have little knowledge of the Android platform, so the following list is a brief summary of the basic materials that I was able to find on this platform:
- The most successful version of a custom code is a graphic code, a digital code (6 digits or more) as an additional option.
- Requesting permissions for certain types of application activity is mandatory and must be performed explicitly for the user with an explanation of what permission will be used for. It is necessary to request a certain permission only in the case of a direct need to use it; also, a request for permission should be shown at the exact moment when it was needed, not earlier. In addition, if the target version of the Android SDK is 23 (or newer), then you should conduct a request for permissions only 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
debuggable
option, in order to avoid the possibility of connecting to the program by an external debugging application. - On the application screens, where the user's private information is placed, it will not be superfluous to prohibit programmatically creating screenshots of the application window, as well as disabling screenshots in the task manager.
- Any private information can be additionally preceded by a request for the user's private key specified by him to log into the application (if any).
- Inside the application code, it is recommended to use
getCanonicalPath
instead of getAbsolutePath
for resolving paths. - Open components used in the application (for example, Service or Content Provider) must be closed with the
exported = false
flag in the Android Manifest. This will prevent access to these components from another application.
In addition, you need to use the available information repositories with care:
Shared Preferences.
- Established security: None.
- Comment: Should be used only for its intended purpose, namely, to store public unprotected user settings. The remaining data should not be posted here.
Databases (SQLite).
- Established security: Depends on the developer.
- Comment: It is an ordinary file, so that all the ARC should be encrypted before recording. The database allows automatic encryption, its inclusion will be a good enhancement of data protection. As the encryption key, it is most advisable to use the security code set by the application user personally (the code, in turn, must be encrypted and stored in the Account Manager, see the description below).
Account Manager.
- Established security: High (only up to API version 18).
- Comment: All KVD should be placed here, but you must first perform additional data encryption. After API 18, use is not recommended.
KeyStore.
- Established 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 of it, in case the KeyStore is available to the developer (API v.18, Android 4.3 and newer).
Conclusion
It is also worth mentioning that the number of protection levels applied depends on the specific application. For example, if the application is not at all client-server, does not contain any KVD, and also does not operate with valuable internal algorithms, then there is no point in attaching any protection to it. If the application is focused, for example, on performing banking operations or storing user passwords, then its degree of security should be the highest. However, the previously listed general mobile sector vulnerabilities can be easily excluded from the application, most often this does not introduce any special additional costs if the application of the required level of protection was started in the early stages of application development. But the implementation of post-factum protection in an already running application may well be associated with significant time and effort of developers. Therefore, the selection and coordination of the level of protection, as well as the list of ARCs in the developed application, should be carried out at the earliest design stages.