Mobile applocation security: How to avoid reverse engineering of an Android app

in security •  6 years ago 

Mobile  app security is the issue of the highest priority for all app  developers and an essential part of product quality. However, despite a  fast-growing mobile market, the level of piracy is disappointing,  especially in Android ecosystem. Unfortunately,  the application is easy to crack, disable advertising, and even untie  from verification services. Making strong efforts to create an app and  hoping to receive income, in the end, you can not only fail but also  “lose” it. Also, some may  wish to crack the app (device, program, software) to find out how it  works in order to steal your ideas to make something better or even just  reproduce it. This practice is called reverse engineering  and used in many spheres including manufacturing and even military. In  this post, we’ll speak about the ways to protect your Android app  against reverse engineering.Applying  to Android, reverse engineering process represents the ways of  extracting a source code and resources from APK file (a zip archive).  APK of a target application can be got from a phone by using ADB or just  by downloading it from Google Play Market.  

PROBLEM:

APK  decompiling isn’t a big deal. By decompiling of an APK file and  transforming dex files -> jar files -> java source codes you can  receive the app source code. And here tools like Apktool, dex2jar,  jd-gui and JAD are always ready to help you out.Nevertheless,  it’s practically impossible to completely protect the product from  reverse engineering and thus ensure the highest mobile app security  level. However, you can make app cracking much harder. Let’s consider our experience in protecting applications. 

OUR EXPERIENCE:

1. Use ProGuard

To  ensure mobile app security and avoid reverse engineering of an Android  application we use a ProGuard tool. ProGuard represents a Java class  file shrinker, optimizer, obfuscator, and preverifier as well. 

It works as follows:

  • The shrinking step is responsible for determining and removing of unused classes, fields, methods, and attributes.
  • The optimization step makes the analysis and optimization of the methods’ bytecode.
  • The obfuscation step renames the remaining classes, fields, and methods using short meaningless names.

These  steps allow making code base smaller, more efficient, and more  complicated to a reverse-engineer. The final preverification step is  responsible for adding preverification information to the classes,  required for Java Micro Edition and for Java 6 and higher.One  should note that obfuscation can be undone by using deobfuscator, where  APK De-Guard is one of the most accurate deobfuscators, as it uses  machine learning for achieving the best results.

2. Move important code parts on the server 

Speaking  about other useful ways and methods that help avoid reverse  engineering, we also move the most critical parts of the service out of  the application into a web service, hidden behind a server-side  language. Imagine, you  have a unique algorithm. You obviously don’t want reverse engineers to  steal it out of your product. So, you can move the algorithm, making it  process the data on a remote server, and use the application to provide  it with the data.

3. Write important parts of code in C/C++ 

Sometimes we also use the NDK to write important parts of our code natively into .so files and add them as a compiled library. While  it can be disassembled into assembly code, reverse engineering process  of a large library from the assembly is rather time-consuming. Comparing  to C/C++, Java is easier to decompile.
 

4. Use SSL 

Apply  SSL when interacting between the server and device. In some cases,  you’ll need your custom certificate. And the class that implements the  X509TrustManager or SSLSocketFactory interface may contain trivial  methods. It can result in a  loss of confidentiality of the data transferred an SSL / TSL protocol.  Often methods of this class are trivial (accepting all certificates),  that makes the application vulnerable in the middle (MitM) attacks. By  providing a valid self-signed certificate an attacker can violate the  confidentiality of the connection and get an access to valuable data.  Even if the methods of the redefined class aren’t trivial, their  implementation is likely to have mistakes leading to the same  consequences.Unfortunately, it’s widespread. Our research showed that about 40% of mobile applications have an incorrect implementation of this class. 

Follow our recommendations to solve the following SSL problems:

  • Check the validity of the certificate each time when establishing a connection via a SSL / TLS protocol.
  • Use standard implementations of X509TrustManager.
  • If  accepting self-signed certificates is necessary, generate your own  X509TrustManager implementation using KeyStore. Also, specify the  certificates that should be taken and reject all others.

5. Don’t store values in a raw format 

Also,  we don’t use a raw format for values’ storage. For example, in case we  need to store a user balance (an amount of application currency) or  other values, we generally save encoded values (for instance, store them  in the form of some algorithm). 

6. Take care of user credentials 

Another our recommendation that will help you avoid reverse engineering process refers to user credentials.

  • First,  it’s better to minimize the frequency of asking for user credentials in  the app. It will allow making phishing attacks more conspicuous, and  less likely to be successful. In this case, we recommend using an  authorization token (also, remember to refresh it).
  • Second,  username and password shouldn’t be stored on the device (where it’s  possible). We advise to complete the initial authorization with a  username and password and use a short-lived authorization token.

In  case you need to allow users to store their credentials to automate  future authentication in your app, use Credential object containing a  user’s sign-in information.

7. Hide your API keys

Usually,  third-party providers use an API key as a convenient authentication  mechanism to grant access to these resources. What’s more, they use it  as the way to charge for their data. Don’t  store the key in shared preferences, assets, resources folders or  hardcoded in Java – an attacker can easily unzip and decompile your APK  and get this key. Use the NDK or Private/Public API key exchange to save  your key.
 

8. Pay attention to hashing algorithm

The  MD2, MD5, SHA1 hash functions have known vulnerabilities. If they are  used to store valuable information (such as passwords), its  confidentiality can be violated. Use secure hash functions (SHA-2).A  hash function used to store passwords shouldn’t only be resistant to  collisions but also shouldn’t be too fast. This complicates the attack  by exhaustive search. For this purpose, specialized hash functions have  been developed: PBKDF2, bcrypt, scrypt.
 

9. Insecure use of reflection

It’s  possible to execute arbitrary malicious code. The method implementing  reflection takes data from an untrusted source as an argument. It allows  attackers to manage the application control flow graph, as well as to  bypass authentication mechanisms and access restrictions. 

Our recommendations:

  • Create  a whitelist of allowed commands and allow the user to choose only from  the list. Don’t use user-entered data directly as an argument of methods  that implement reflection.    
  • If  the reflection is used in conjunction with configuration files, ensure  the integrity and uniqueness of these files. Don’t set the reflection  parameters in the configuration files in the absence of significant  resources for solution security analysis.    

10. External storage usage

Files  written to the external storage device are readable by all applications  and can be changed when the user connects the device to the computer in  a USB drive mode. Besides,  files stored in external storage will remain there even after the  application is deleted. It may result in the valuable data  confidentiality loss. That’s why we store files in the internal memory  or use SQLite database.Nevertheless,  to completely protect an application from reverse engineering is almost  impossible. However, these ways and practices help us maximally secure  Android apps. We advise you to use them to protect your mobile solutions from cracking and provide a higher mobile app security level.
If you have some questions, need a consultation about security issues, or have a project idea, feel free to apply to a reliable mobile app development company to get meaningful recommendations. 

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!