Mobile applications are increasingly used in all areas of business: HR, finance, insurance, transport, and so on. As a result, they are prime targets for attackers.
There are several ways of assessing the security of a mobile application. In this article, we present the “offensive” approach, which we believe to be the most effective: mobile penetration testing (or mobile pentesting). We detail the principles, objectives, methodology and features tested during mobile application penetration testing.
- What is a mobile application penetration test?
- The ecosystem of mobile applications
- Scope of a mobile penetration test
- Focus on OWASP’s Mobile Application Security Verification Standard (MASVS)
- Insecure storage of sensitive data
- Disclosure of sensitive information in logs
- Network communications security
- The application’s permissions
- Deep links on Android
- Sensitive data in the application code
- Support for older versions of iOS or Android
- The Android Janus vulnerability
What is a mobile application penetration test?
A mobile application penetration test consists of evaluating the security of a mobile application by simulating the conditions of an attack.
In general, it is rare to find a mobile application that does not communicate with one or more servers. Therefore, a mobile penetration test includes:
- Server-side tests by analysing communications, usually HTTP/HTTPS. In this case, the tests are identical to a web pentest. And it is generally on this side that the most critical vulnerabilities are found. However, it may happen that the application does not communicate with a server, or uses other protocols such as MQTT.
- Specific tests relating to the mobile application’s own features.
These different assessments will be examined in detail in the following sections of this article.
The results of the tests are recorded in an audit report that details the methodology used, the vulnerabilities discovered, their impact, possible exploitation scenarios and recommendations for fixing them.
The ecosystem of mobile applications
Nowadays, Android and iOS account for 99% of operating systems. So we’re only going to talk about these two major players here.
Then there are several different types of applications:
A native application is one that uses the SDK (Software Development Kit) to create applications specific to the OS. The advantage of native applications is their performance, and the ability to interact with most of the phone’s components (sensor, camera, etc.). The notable disadvantage is a divergence in the code base, leading to significant differences depending on the target. Even the programming language is different, generally Java or Kotlin for Android and Objective-C or Swift for iOS.
However, there are frameworks that provide a common base. Examples include Xamarin, Flutter and React Native. Despite the common base, the final application can be considered as a native application with the same level of performance and access to the same components as using the SDKs directly.
Hybrid applications are applications that run primarily in a WebView, i.e. an integrated browser. The advantage of hybrid applications, unlike purely web-based applications, is that they can access the device’s functionalities.
As with native applications, there are several frameworks for creating these applications, including Cordova and Ionic.
Progressive Web Apps (PWA)
These applications load like ordinary web pages, but with a few differences from traditional web applications, such as the ability to work offline and to access certain hardware features.
Scope of a mobile penetration test
Focus on OWASP’s Mobile Application Security Verification Standard (MASVS)
MASVS is the standard for mobile application security. This enables us to guarantee the completeness and consistency of test results.
OWASP classifies the various checks to be carried out on mobile applications into 7 sections:
- MASVS-STORAGE: ensure secure storage of sensitive data.
- MASVS-CRYPTO: implement cryptographic features to protect sensitive data.
- MASVS-AUTH: implement authentication and authorisation mechanisms within the mobile application.
- MASVS-NETWORK: guarantee the security of data in transit during communications.
- MASVS-PLATFORM: ensure the security of interactions between the mobile application and other installed applications.
- MASVS-CODE: follow best practice in data processing and application updates.
- MASVS-RESILIENCE: strengthen resilience against reverse engineering and forgery.
This list gives a good representation of the families of vulnerabilities that we can identify in mobile applications.
Depending on the type of application, the requirements in terms of security will vary, so we will adapt the types of tests according to the needs in terms of security.
In the remainder of this article, we will not present an exhaustive list of all the vulnerabilities inherent in mobile applications, but only those we encounter most often during our penetration tests.
Insecure storage of sensitive data
In general, mobile applications need to store certain data on the phone in order to keep it in memory. We strongly advise against storing the user’s password directly on the phone. It is preferable to use a session token instead.
Furthermore, it is essential to properly manage the storage of this session token on the phone. On iOS, this should be done using the keychain, while on Android, the keystore is the appropriate place.
Unfortunately, it is not uncommon to find sensitive information stored in inappropriate ways, such as in SharedPreferences on Android, NSUserDefaults on iOS or even SQLite databases.
However, accessing this data is complex and generally requires physical access to a rooted/jailbroken phone.
Android has 4 ways of storing data: application-specific storage, in a database, in preferences and shared storage.
The first 3 are only accessible to the application, unlike shared storage, which is accessible to all applications.
If an Android application uses this storage for sensitive data, it will be accessible to everyone and a malicious application will be able to exfiltrate it. For example, imagine an application that saves the cache of HTTP requests in shared data. This cache may contain sensitive information such as an authentication token. A malicious application could exploit this vulnerability to steal the token.
Another example that works on iOS and Android is the use of the Download directory. If this directory is used, it is important to bear in mind that a malicious application will be able to access the data in it (invoices, for example). Even if this is not necessarily a vulnerability in itself, it is important to greatly limit the use of the download folder.
Disclosure of sensitive information in logs
As a general rule, it is advisable not to record logs in a production application, or at least to ensure that no logs contain sensitive information such as passwords.
However, access to application logs requires physical access to a phone. On Android, you also need to activate USB debugging mode, which means activating developer mode.
For example, let’s say an application stores the authentication token appropriately. However, if it is displayed in the logs, an attacker could connect the device to his PC and retrieve the token by listening to the logs.
Network communications security
When we talk about network communications, we often think of Man in the Middle attacks, where an attacker tries to impersonate the server to the application.
Several types of protection can be implemented on devices to guard against these attacks as effectively as possible:
Authorise HTTPS connections only
Restricting connections to HTTPS only can be implemented on Android using
cleartextTrafficPermitted="false" and on iOS by activating
This measure is equivalent to implementing the HSTS (HTTP Strict Transport Security) directive found on standard websites.
This guarantees that all exchanges will take place securely and prevents attackers from redirecting to an unsecured site, as well as protecting against server configuration errors if the server does not redirect HTTP connections to HTTPS.
Check the HTTPS certificate
It is important to ensure that the certificate is valid, approved by a certification authority and not self-signed. This makes it difficult or even impossible for an attacker to get into a Man in the Middle position.
Take Alice, for example, who is on an insecure network and is using an application that communicates using https but does not verify the certificate. Bob can generate his own self-signed certificate and if he manages to put himself in Man in the Middle, he will be able to usurp the server.
It is possible to take certificate verification a step further using certificate pinning. The idea here is to check that the certificate is actually the one expected. This adds a defence in depth to ensure that the communication is actually with the expected server.
For more information, you can consult our dedicated article which explains the principle and operation of this type of mechanism:
The latter is recommended for mature mobile applications, so don’t invest too much time in it if you’re just starting out.
The application’s permissions
In some cases, a mobile application needs to request authorisation for specific actions (e.g. retrieving location information). It is good security practice to limit permissions to what is strictly necessary.
In addition, it is advisable to inform the user of the need for this permission in order for the application to function properly. The principle of least privilege should be the norm here.
Deep links on Android
Deep links are predefined URIs (Uniform Resource Identifiers) that provide direct access to a specific functionality of a mobile application when clicked. However, their use can lead to potential vulnerabilities if they are poorly implemented.
Transfer of sensitive data through deep links
This means that if a malicious application is installed on the mobile, it can open instead of the legitimate application.
For example, let’s say we have a password reset link in the following format: If the malicious application can open this same type of link and is selected by default, then it can recover the code and, for example, exfiltrate it.
Dangerous use of parameters transmitted via deep links
The problem here is not how the data is transmitted, but how the parameters are used.
Let’s take the following example:
The application opens links beginning with “myapp” and, depending on the parameters, performs the associated actions. The actions include “deleteaccount” if Bob manages to get Alice to access the following link via phishing, for example:
This will have the effect of deleting the account.
We have written a detailed article to explain these issues in more detail:
Sensitive data in the application code
It is always possible to recover the source code of an application, more or less easily depending on the technology. So it’s important not to store sensitive data such as SSH keys, passwords, etc.
Let’s take a concrete example. During an audit, we discovered an Access Key ID and Secret in an AWS application, which enabled us to impersonate a developer and escalate our privileges.
The following Github repository shows the secrets that can be leaked on mobile applications:
In addition, the application must never replace the server for security checks. For example, the authentication token must not be generated on the application, as this could lead to account theft:
Support for older versions of iOS or Android
This issue is particularly worrying on the Android platform, where support for older versions of the operating system is commonplace. However, in 2023, it is strongly recommended to target at least Android 8.1 to benefit from significant security updates.
According to data from Android Studio, this allows the application to run on around 90% of devices. So authorising the application from this version onwards offers a judicious balance between security and accessibility.
The Android Janus vulnerability
In 2017, a significant vulnerability was discovered in Android allowing the application code to be modified without changing the signature (only the V1 signature). This can allow an attacker to deliver a malicious application that looks legitimate. To protect against this, you only need to support the V2 and V3 signatures on Android.
Most of the time, the V1 signature is present to ensure that the application can be used on older versions of Android, below 7.
The Janus attack works as follows: when an application has a Janus vulnerability, an attacker is able to incorporate a malicious Dex file into the application without altering its signature.
As a result, if a user downloads the application and already has the original version, this modification will be perceived as a simple legitimate update.
Author: Thomas DELFINO – Pentester @Vaadata