The most common questions I get from mobile application security analysts pertain to man-in-the-middle (MiTM) attacks. Many people don’t understand the repercussions of these attacks or know what security controls to incorporate in their mobile apps to avoid these issues.
In basic terms, a MiTM app attack equates to eavesdropping. They occur when an app is communicating with a server and an attacker covertly intercepts those communications to observe sensitive data such as usernames or passwords.
But attacks don’t end at this breach of confidentiality. He or she can also change the content of these conversations by changing request parameters or results returned by the server. That means an attacker can potentially modify the user interface, authentication flow, or error handling performed by an app. For example, an attacker might change the amount of money transferred in a financial transaction or switch your taco delivery order to a burrito.
In this guide, you’ll learn:
- The development mistakes and security issues that can leave apps vulnerable to MiTM attacks
- Tips for testing to ensure apps are impervious to MiTM exploits
- The layers of network defense that can help prevent these issues.
How MiTM Attacks Happen
Many security analysts find it difficult to perform MiTM testing to assess mobile app security. The process is often their first introduction to using dynamic analysis tools like Frida, as well a reminder that you need devices to perform mobile application security testing. But intercepting mobile app network traffic is easier than they realize, which means that attackers can do it too.
While mobile app MiTM attacks stem from app client-side issues resulting from bad code, the scenarios required to successfully execute them can vary based on the app’s threat model. The most well-known scenario is the interception of unprotected network traffic.
Network Traffic Interception
There are many ways for a hacker to intercept network traffic. One scenario people frequently warn users about is “Free Wi-Fi.” Users join a free Wi-Fi network unaware that the provider is snooping on all their data.
In reality, network issues can happen on LTE networks, over free virtual private network apps or many other scenarios. There’s much debate over who might be intercepting connections and how, so it’s best to operate under the assumption that networks are hostile.
Mobile App Network Security
In addition to having the ability to intercept network traffic, the other criteria for a MiTM attack is lack of authentication. This occurs due to problems in an app such as improper hostname verification or certificate validation.
The Internet relies on protocols like HTTP and HTTPS as the foundation for all our network communications. The simple difference between these two protocols is HTTPS uses cryptographic protocols that can potentially protect your data through authentication and encryption, and HTTP does not. I wish I could tell you that in 2019, every mobile app uses HTTPS to send and receive requests. But I’d be lying — far too many Android and iOS apps today still use HTTP.
This issue may already have you grinding your teeth, but the problem gets worse. Sometimes even when mobile apps use HTTPS, developers configure it incorrectly. These issues are scarier than the use of HTTP because they lead to a false sense of security.
During the TLS handshake, it’s up to the client to verify that the server’s digital certificate is valid. When done correctly, this step establishes the authenticity of the server to verify the app is connecting to the intended server.
You might be curious what exactly is being verified. In general, we are validating the certificate is issued and signed by a valid Certificate Authority (CA) intermediate, is not expired, and is part of the system’s trust anchor. On top of that, we also want to verify that the server’s hostname matches the field of that certificate.
We routinely encounter mobile apps that aren’t performing the certificate validation process. During the verify process, an app will accept a self-signed certificate. If you’ve ever spun up your interception proxy and could intercept traffic without configuring a cert on your device first, your app likely has issues with certificate validation.
Hostname verification problems can reveal themselves when apps accept valid CA certs with an invalid hostname. In this scenario, attackers could intercept traffic with a cert registered for a domain that doesn’t match the endpoints that they’re eavesdropping on.
When a browser encounters one of these issues, it will likely display an error message similar to the one below:
It’s up to the developer what to display if an issue occurs during the verification process. In other words, if a mobile app is susceptible to MITM attack, users probably won’t be aware that it’s happening and the developer probably isn’t either or doesn’t understand the impact. The common misconception about mobile apps are these processes are handled by the system, similar to how browsers would handle these events, but this is untrue.
Another common misconception is mobile development I see is that iOS’s AppTransportSecurity and Android’s NetworkSecurityConfig can enforce these processes, but neither are able to enforce the hostname verification process.
At their core, MITM issues primarily impact users. A user who has their data intercepted by an attacker can have confidential information exposed. The integrity of the data, sent and received, from the intercepted endpoints can be compromised as well. This means that an attacker who is able to successfully perform a MITM attack can potentially modify the UI, authentication flow, or error handling performed by an app.
At a bare minimum, ensure apps perform hostname verification and certificate validation and implement these correctly. But unfortunately it’s not that simple. Remember how networks are hostile? Mobile devices can fall into a similar camp as well. As a security professional, it may be tempting to believe that your app is going to only be installed on a modern, updated device whose user is on top of all the phishing vectors out there, and the CAs are perfect in every way, but hopefully you know better.
CAs have been compromised, issuing digital certificates to malicious actors. The challenge doesn’t end there. As it turns out, tricking a mobile device into believing that a self-signed certificate is valid is possible and does not require a jailbroken or rooted devices. Both mobile platforms allow users to add certificates to the device trust anchor. It’s more than likely that if you’ve used an interception proxy to observe HTTPS traffic from your device, then you’ve added a certificate to a device’s trust anchor.
It’s not all sad news. As of Android 7, installing a certificate and having it recognized as a system cert now requires root access. Network Security Configuration allows developers to decide if they want to accept user installed certs, but by default, only system certs are accepted. And of iOS 10.3, trusting a certificate requires the user to go through an additional workflow. In addition, there are a few other methods to validate certificates.
Network Security Defense
Apps that require a higher level of security or regulatory compliance or contain financial or health data can use certificate pinning. The trick is managing the cert. If it expires or needs to be revoked, you’ll likely need to update the app. The other challenge is that it’s tough for third-party code to support pinning. If you include some analytic tools in your app, they likely make network requests. Not only would they have to worry about the typical certificate pinning issues apps deal with, but they would also have to make sure that every app that uses their framework is up to date as an outdated version with an expired cert may break an app.
Certificate Transparency checks are one of the more modern options I’ve seen adopted for apps that require a high degree of network security. Certificate Transparency is an open framework for logging, monitoring, and auditing the issuance of CA certificates. When implemented correctly, Certificate Transparency adds a layer of public monitoring to the CAs and the certs you use for those pesky HTTPS connections.
Because Certificate Transparency is still fairly new in mobile, best practices are still being created. iOS lets you check a certs signed certificate timestamp using the `SecTrustSetSignedCertificateTimestamps` function. On the other hand, Android has Conscrypt security provider which as a `CTVerifier` class can also check signed certificate timestamps. Checking a cert for SCT is a good way to determine if the cert is a legit CA cert, and not a self-signed sideloaded cert.
Checks like these are not meant to replace the other process that your app should already be doing, like hostname verification and certificate validation. They are meant to add an additional layer of security. I’ve seen apps perform CT checks and other similar verifications, only to be subject to MiTM attacks because the app doesn’t perform hostname verification.
What’s more, another major misconception around certificate pinning and other CA audit controls is that they prevent all MiTM attacks. Tools like Frida make these controls bypassable. The trick here is that the attacker will likely only be able to bypass these controls on root or jailbroken devices that they have physical access to, and have the skills to understand the protections that are implemented within the app. So that means they can really only launch a MiTM attack on themselves.
This leads into another common misconception — the intention of technologies like certificate pinning is not to protect the client’s API but rather to protect the mobile app user’s information.
When we start breaking down all the network security requirements that could go into a mobile app, what will ultimately be the deciding factor is the type of data your app handles. It’s not feasible to expect every app to perform certificate pinning on every request. But these network security practices narrow the scope of a MiTM attack scenario further so that one can’t be carried out without physical access to the device.
Mobile App MiTM Testing Tactics
Finally, just as important as understanding these levels of protection is getting a handle on testing. It’s important to test each of these MiTM scenarios to discover where your app might be leaking data. Try these tips for testing mobile app susceptibility to MiTM attacks.
- Use a proxy that lets you choose the cert type you want to test with. That means not only testing with the cert installed to your device, but also self-signed and a CA cert registered to a domain that doesn’t match any of the endpoints you’re connecting to.
- Try proxying off an interface instead of proxying using the device setting. A lot of apps are being made proxy unaware, meaning they won’t adhere to the proxy rules you put on your device. This could result in some pretty ugly false positives. By setting up an interface that you collect all data from and using iptables rules to forward traffic to your proxy of choice, you can make your MiTM setup top notch.
- Lastly, get jailbroken and rooted devices. You will eventually encounter apps with certificate pinning. Rather than trying to recompile apps to bypass these controls, use a dynamic instrumentation tool like Frida to get around these issues. Not only are these devices useful for this type of testing, but provide one of the only ways to do mobile app security testing.
In the end, remember that the mobile app attack surface is broad and requires skills across several areas of testing. For help figuring it out, I highly recommend consulting OWASP Mobile App Security Verification Standard and Mobile Security Testing Guide. Also check out the “Manager’s Guide to the OWASP Mobile Application Security Project.”