What is certificate pinning and how is it implemented for iOS and Android?
In this blog post, we will look at certificate pinning, how it is implemented for iOS and Android and the associated risks of using this added security control.
What is certificate pinning?
Mobile applications typically communicate with a TLS-supported endpoint, mainly if sensitive data is transmitted. During that SSL handshake, the mobile application will verify the server’s certificate through the chain of trust.
Typically, mobile applications accept any server request with an SSL certificate without filtering. Certificate pinning is added to increase the network security for these applications.
With certificate pinning, the backend server is associated with an X.509 certificate or public key. Instead of accepting any certificate signed by a trusted certificate authority (as we saw above), the application is designed to accept only specific trusted certificates.
After pinning the server certificate or public key, the mobile application will only connect to the known server. The application will not trust custom certificates and, by default, will not allow proxy tools (burp, MITM Proxy, etc.) to intercept the traffic.
Why use certificate pinning?
Essentially, if you use certificate pinning, you are removing the trust from external certificate authorities, thus reducing the overall attack service and adding a layer of security to your mobile application.
How many applications are doing this? While many applications still do not do certificate pinning, it is becoming increasingly popular within the financial sector. Certificate pinning by default makes traffic interception difficult and decreases the overall attack surface and complexity required to attack your mobile application.
Certificate pinning types
Certificate pinning is used to attach a list of trustworthy certificates to the mobile application during the development phase and compare it whenever a server request comes during runtime. Only allowing pre-defined certificates to interact with the application when intercepting traffic. There are two main ways available for certificate pinning:
Embedding the certificate
The developer will hardcode the SSL certificate (X.509 certificate) into the mobile application code. When the mobile app communicates with the server, it checks whether the same certificate is present.
If the certificate is the same, the application proceeds with the communication; otherwise, the user will see an error from the application.
The major downside of this type of certificate pinning is that if the certificates are rotated regularly, the application will need to push an update to prevent authorized users from gaining access to the app.
Public key pinning
Instead of adding the entire certificate in, as we saw above, only the public key gets embedded in the mobile application to compare the server's public key with the embedded one. When it comes to public key pinning, it can be more flexible but also definitely tricker due to the extra steps necessary to extract the public key from the certificate.
Now that we know about the two different options for implementation, we can take a deeper look into the three types of certificates that are used for certificate pinning implementations:
Root – If the certificate does not match during validation, it checks the issuing CA’s to see who was authorized until they reach a trusted CA.
Intermediate – This required trust in the Certificate Authority. As long as the certificate comes from the same provider, any changes to the leaf certificate will not affect the application.
Leaf – If the pinned certificate is expired, it will disrupt the application until it is updated; this gives a lot less time before expiry and can impact your application users if not maintained correctly.
How to implement certificate pinning
There are a variety of methods for implementation for both iOS and Android, which I will break down below for your information:
iOS certificate pinning
1. Alamofire certificate pinning
This is a very popular HTTP networking library for the swift language. It also has built-in functionality for certificate pinning, which many applications use. Alamofire has the ServerTrustPolicy.certificates method, which returns all the certificates within the bundle; this approach requires pinning only the pre-defined domains instead of all application domains.
When it comes to an authentication request from the server, the client will first request it for their credentials. The server’s certificate is compared with those saved within the mobile app bundle; if it matches, you are good to go.
All the checks are done manually for this method to implement the certificate pinning.
Android certificate pinning
For Android, there are a handful of ways to implement certificate pinning. I will talk about some of the most common; there are some other third-party libraries and ways to implement certificate pinning depending on your application development.
1. Network security configuration
Since Android 7, the preferred way for implementing certificate pinning is by leveraging Android's built-in Network Security Configuration feature. This is extremely easy to implement and allows for customization without modifying the mobile app code.
2. OKHTTP and CertificatePinner
OKHTTP is a popular HTTP client library for Java that many applications utilize. Within the OKHttp library, your application can use CertificatePinner to enable certificate pinning for your mobile application.
TrustManager is an android component responsible for deciding whether the mobile application should accept credentials submitted by the peer for now.
As I mentioned above, depending on how your application is developed, Android has a few additional options. Still, these three typically become the front runners for most android mobile apps that choose to implement certificate pinning.
Issues associated with certificate pinning
Certificate pinning as a whole is still looked at apprehensively by a lot of mobile development companies due to a few reasons, which I will summarize for you:
Implementations can be complex and time-consuming depending on the application and how it is developed.
There are various methods to bypass certificate pinning; on its own, this added security control does very little to improve the overall protection of your mobile application.
Which certificate is pinned can require regular updates to the application and for the users to maintain continuous access.
Where does Corellium come into applications that utilize certificate pinning? In a mobile pentest, typically, you have two options: the development team provides multiple builds where they remove certificate pinning and additional security controls in a build for ease of testing, which in this case, testing can resume on the Corellium platform as you normally would.
The other option is that the development team will provide the prod build with the security controls enabled; if that is the case, Corellium does offer a built-in network monitoring tool that can be utilized to review traffic being sent from your application to the backend while bypassing certificate pinning. This is not offered out of the box from any other provider; if you wanted to intercept traffic for a mobile application that still keeps these controls in place, you would need to bypass the implementation, which we will discuss in another blog post.
Certificate pinning can be a solid addition to improve your mobile security. Still, it is much less effective when additional security controls are not utilized (root detection, tamper-proofing, runtime protections, etc.). When an application running certificate pinning is allowed to be installed on a rooted de, there are numerous ways an attacker can defeat certificate pinning and access the application
Stay tuned for our follow-up blog on bypassing various certificate-pinning implementations.