Mobile AppSec: Security Considerations for Finalized Mobile App Distributables

It is important to understand that mobile apps are client-side applications. Anyone with the final package binary/installable bundle can easily reverse engineer or extract data from the application. We will explore some common risk and demonstrate how an attacker can take advantage of insecure coding practices.

Eric Goldman
Walmart Global Tech Blog
11 min readMay 26, 2021

--

Photo by Lajos Szabo on Unsplash

Post release protection is the process of making it hard for an attacker to exploit your application or attack your service once you release the app to the AppStore, Google Play, or similar. Unlike with web applications, the attacker has access to your binary introducing the possibility of reverse engineering, tampering, and exposure of information.

The purpose of writing a mobile app, instead of relying on a web app, is that more storage, functionality, and processing are performed client-side. As a result, more data and functionality is available for inspection by an attacker compared to a web app, where most processing takes place on the server and most apps do minimal storage or local processing. Therefore, you can no longer rely on server-side protections and must be more cognizant of code quality and data exposure. Even if your code is complex, obfuscated, minified, etc. a skilled attacker will be able to reverse engineer your application. Beyond being able to trace the code level flow, an attacker can also search for embedded metadata or other useful strings like passwords or other secrets. Reverse engineering may also reveal unused or deprecated functionality which is not publicly known.

Be Careful — You must ensure you have a carefully crafted build pipeline that prepares your code to be ready for production. By minimizing functionality and data in your final binary you reduce the attack surface for the hackers and fraudsters.

Watch Out — Your Information Security team must always on the lookout for fake apps, imposters, or tampered distributions. By being aware of the risk of reverse engineering, tampering, and exposure of unnecessary data and functionality you can help reduce the number of malicious apps out there.

What could go wrong?

Any time you provide a user with a binary, an attacker has the opportunity to reverse engineer the app for data discovery or for illicit patching with malicious features.

While the Google Play and Apple’s AppStore feature secure methods to deploy your apps, an attacker may still be able to get bit-level access to your binary and previous versions of the binary in order to reverse engineer or perform other analyses on your app. While you cannot prevent the analysis of binaries, you can reduce the risk with careful planning.

Consider some of these tactics used by fraudsters and attackers:

In the case of Android, there are third party alternatives to Google Play. While some are large and monitored, others are fraudulent and malicious. For example, someone could make a blog promoting a “special version” of your app and then provide instructions to “side-load” the app; this would allow them to bypass any review processes or other user-security benefits of the official Google Play service. Instead of making an fake app with limited functionality, the hackers instead reverse engineer and patch your real, official app. Their modifications may include adding requests for new personal data ,which they then harvest with their servers, or they may simply add man-in-the-middle exfiltration of data and transactions.

An attacker may perform reverse engineering, string analysis, and other analyses of the binary file. The attacker may be able to find a call to a deprecated API that was commented out, but which was not taken offline, and abuse this functionality. The attacker may also find embedded metadata, comments, or other information to attack the server-side components of the application.

Defensive Considerations

Ensure you have clearly defined build environments and separate configuration settings which are clearly defined, enforced, and checked. For example, you may enable debugging or turn off two-factor authentication in a testing environment. If you release an app update to the public with “dev environment” settings it reduces the security of your application. Unlike with a web app where you could push out a new version to all users by making an update on your server, some users may choose to skip an upgrade and may be left with a vulnerable version for a long time.

An app in production should be hardened and minimal. Only include the minimum amount of functionality and data. Remove unused and unnecessary code before deploying. Unused functions / methods are typically still available when the application is reversed, even if they are never called. A common misstep is to hardcode both production and UAT information in the app and then use branching logic (if/else) to select the correct information. Since the attacker can obtain the full source code, perform reverse engineering, or at minimally debug flows, details about the non-production environment could be exposed to the attacker. Your build process should strip out all comments and unneeded information, especially if you are using a non-native app development platform like Apache Cordova or React Native.

Be conservative with what functionality you perform in the client versus on the server. For example, it is usually better to proxy requests through your server than to have your mobile client directly contact third party APIs when you would have to include your developer key for that third party API.

Lastly, you cannot prevent reverse analysis, but you can make it more difficult by utilizing obfuscation and anti-reverse engineering techniques. However, a skilled attacker may still be able to trace your application and and some techniques may not significantly increase the difficulty of extracting hardcoded strings.

Reverse Engineering Walkthrough Example

Walkthrough Overview

To demonstrate the ease in which hackers and other adversaries can reverse engineer your mobile applications we created a very simple stub application.

The application doesn’t do much in its current state; it simply loads a main screen with a message. However, within this application there is a lot of information below the surface that could easily be extracted through reverse engineering.

In this demo, we will show you how an attacker can use simple and free tools to extract useful information that many developers think is secure and protected.

Let’s walk through some of the key source code for this application.

Basic Activity Layout (activity_main.xml)

The activity layout for a file contain the UI layout for our application. You can see in the screenshot below, the only UI feature we have is a text field with static content that says “Can you find my secrets?”. There are no buttons or any other UI features of this application.

The main activity (i.e., end user UI view) for the application (activity_main.xml)

Main Activity (MainActivity.java)

This is the main activity that is run when the application is launched. Currently, there isn’t much going on in this application. We can see that it looks like the app will eventually call some remote API or service, the apiKey key variable is hardcoded on line 8 of the application.

The “main” method for the Android application, loads the Activity defined in activity_main.xml (MainActivity.java)

HTML Asset (awesome-web-view.html)

In this web app, in addition to writing some native code, the developer plans to also do some work using a WebView so that that work can be performed by the JavaScript expert on his team. For the time being, there is just a small stub. Notice the comment on line 4 in this file. On Line 5, we can see a hardcoded apiKey which was also used in our MainActivity.java file above. It looks like the remote content will be fetched using the code starting on Line 7.

An HTML file in our assets folder that has a comment and a hardcoded API key (awesome-web-view.html)

SQLite Asset (passwords.db)

In the above screenshot, you may have noticed another file in the assets folder (/app/src/main/assets). This is a SQLite database which happens to store some passwords in one of the columns. It looks like in addition to contacting some web services that use API keys, the app will also need to authenticate using some username and password combinations. Here is the content of this database:

A GUI view of the schema an data contents in the passwords.db file.

Reverse Engineering Walkthrough

How to open and explore and existing *.apk

Now that we have seen what the app currently looks like from the developer viewpoint, we will explore how a hacker or other adversary could easily reverse engineer our app and extract variables and assets.

To perform the reverse engineering analysis, we will use a simple GUI-based, open source tool called JADX. JADX makes it simple to open up a *.apk file and to review the source code. JADX take the Dalvik bytecode and converts it back into a readable JAVA code. In many cases, the output JAVA will be exactly the same as our original source making it very easy to trace and check the file.

To use JADX, it is as simple as loading the JAVA app / platform executable and then opening the file. An attacker can obtain your app’s *.apk from an online app marketplace like Google Play or could export the *.apk once installed locally on the mobile device using a backup tool. Check out this article showing many simple ways to get an app’s *.apk file. Similar techniques are possible for other platforms.

Here is a screenshot of JADX when it loads:

Screenshot of JADX tool before your load any APK file.

Here is how simple it is to open and start exploring the *.apk file:

That’s it, no magic — just use a standard file open dialog and you can be a reverse engineer (JADX File open dialog)

There are other reversing techniques and tools that can help if there was obfuscation or other anti-reverse engineering techniques. Remember, obscurity is not security.

Screencast of Reverse Engineering Analysis

The following video shows how easy it is to use JADX to explore the content of the file once you open it with the above dialog. JADX shows the various files in a source tree much the same way we would expect while using an IDE like Android Studio. Watch the video and then consider the points below.

Screencast of reverse engineering with JADX and finding hardcoded secrets in the APK.

To start our analysis, we navigate the applications file tree to com.example.hiddensecrets (Hidden Secrets is the name of our app). Under this tree, we see the files and key variables that are available. The most immediate thing that should jump out to you is that the hardcoded apiKey is right there for anyone to see and steal; there is no special obfuscation or magic. Hardcoded strings are almost always available during reverse engineering.

Screenshot showing that the API Key is easily discoverable in JADX inside the MainActivity

There isn’t much going on in the application itself, so the next logical place to look are in the application’s resources. Under the resources we see some common files like the AndroidManifest.xml, but there is also the assets folder that holds the HTML file used for our WebView as well as the SQLite database we plan to analyze.

Again, in the HTML file our hardcoded apiKey is easily accessible and could be stolen by the attacker to gain unauthorized access to services and data. In addition, you will notice that on line 4 the JavaScript comment is visible and present. When Android Studio builds the app, it will generally strip out comments in Java files, but it will not perform similar analysis and comment removal on other file types. This mean any comments you leave embedded in HTML, JavaScript, or file metadata will be accessible to anyone who can get a copy of your app’s *.apk.

Lastly, within JADX we can also see the plaintext data embedded in our SQLite database, passwords.db.

Using JADX to view the passwords.db file inside the APK
Scrolling to the right inside password.db, the SQLite file can easily be viewed and plaintext data extracted.

It may be a little difficult to scroll through a database or non-plaintext file using a tool like JADX; however, JADX is not the only way to analyze assets within our *.apk.

An *.apk is actually just a zip-file like container. This means that we can use a common unzip operation and then we can see all of the source Dalvik files and non-Java assets. In the screenshot below, you can see that after unzipping the *.apk we can navigate to the assets folder and the files will be there for us to open.

Viewing the unzipped APK file in Windows Explorer

Now that we have unzipped the assets, we can use any tool we want to analyze them. We don’t need special hacker tools to analyze the SQLite file. We can use a common tool, such as DB Browser for SQLite to easily go through the contents of this database. Using this free browser tool, the attacker can easily work with the data, see the database structure, and do more. Review the screenshot and video below to see how trivial it is for an attacker to access this highly sensitive data once they unzip the *.apk:

Screenshot showing how the passwords.db file was recovered using DB Browser For SQLite

You can watch this video to see the full opening process:

Screencast of opening the passwords.db file in DB Browser for SQLite

Walkthrough Takeaways

Anytime an attacker can access the binary or other assets, reverse engineering is possible. While there are obfuscation and other techniques possible, there is also the possibility that such techniques can be defeated. As a developer, you must assume that any data, algorithms, etc. that are in your client-side executable/binary will be found and analyzed. While performing local processing and storage can often make sense, performing operations and storage on your server is often more secure since attackers cannot easily see the source code running on your server in the same way then can with a client-side executable.

In our demo we used a very simple tool; however, there is an entire ecosystem of more advanced reverse engineering tools available for free or at little cost that can be used to do deep analysis regardless of your platform or other protections.

Wrap Up

When it comes to mobile apps, it is important to remember that anything and everything in the client-side distributable can be accessed. It is important to remember that hard to dig through is not equivalent to impossible to dig through. When building your mobile apps, you must ensure that everything on the client-side is sanitized and cleaned up before your deliver — comments, unused functions, and strings are all there for the taking. The less you expose client-side the more secure your will be.

Want to learn more about AppSec? Check out my other articles here on Medium. If you liked this article, don’t forget to hit the clap button 50x 👏 and share 🎁 with your friends on social media. Feel free to comment below with ideas and questions.

Read more by Eric H.Goldman:

OWASP Mobile Top 10 (2016) topics covered in this article: M8: Code Tampering, M9: Reverse Engineering, M10: Extraneous Functionality

--

--