
Secure Mobile Application
Development
Part 3: Certificate Pinning
Jahmel Harris, Technical Director
Attack Scenario: 2, 3
SSL/TLS works using a chain of trust, where a certificate is used to validate the connection to the endpoint. In order for the certificate to be trusted, a list of trusted Certificate Authorities (CA) are stored locally on the device. Although a full explanation of Public Key Infrastructure (PKI) is out of the scope of this piece, in brief a trusted CA will sign a certificate for a particular domain once proof of domain ownership has been established. This allows the client and endpoint to securely exchange a set of keys which can be used to encrypt data for that session.
One of the weaknesses of this approach is that should a trusted CA be compromised, any certificate signed by their private key will be valid and trusted. Alternatively, should an attacker be able to install a rouge CA into the trusted CA list, any certificate signed by this CA will be trusted and valid. The strength of this approach is that any endpoint using SSL/TLS can be trusted assuming you can trust the CA which signed the certificate in use.
Whereas a web browser is used to connect to many website, mobile applications have the benefit of knowing beforehand the domain(s) they will connect to. This means it is possible to increase security by trusting specific certificates, rather than specific CAs. By using this approach, a certificate signed by a compromised or rouge CA will no longer be valid and trusted by the system. This can be done by hardcoding the public key of the trusted certificate into the application binary.
Depending on the application, a choice should be made on which certificate to pin against. As a certificate chain is presented to the client, a more secure approach will be to pin to the server certificate. This means no CA needs to be trusted and a self-signed certificate can be used. It does, however, mean that should the certificate need to be invalidated, a new version of the application with the new certificate will need to be released.
Pinning further up the chain will slightly decrease security, but allow certificates to be changed without requiring a update to the application. If pinning against the CA certificate, a compromise of that particular CA would allow an attacker to perform a man in the middle attack on the connection, however the application would still be protected against compromises of other CAs and from rogue CAs installed on the device by an attacker.
Pinning against the leaf certificate will provide the most security as trust is no longer given the the CA or any intermediate certificates.
As well as pinning against a certificate, it is possible to pin against a certificates public key.
Care must be taken on deciding where to store the pinned certificate. If the certificate in stored as an application asset, an attacker may replace it with their own certificate. If the certificate is hardcoded into the binary and protected with obfuscation, it is more difficult for an attacker to replace the binary, however it will also be more difficult to update if needed. It is also possible to pin against the first certificate presented by the server and Trust On First Use (TOFU) however this is not often recommended and an attacker in a position to intercept the first request will may be able to intercept all future requests.
Should a certificate be presented to the application that differs from the pinned certificate or public key, the application should drop the connection and inform the user.
iOS
Several libraries exist which allows developers to create pinned connections. Some recommendations include TrustKit and AFNetworking.
NSURLConnection
iOS does not provide a native approach to perform certificate pinning. Instead, a NSURLConnectionDelegate can be used to implement
A sample implementation in ObjectiveC can be found here.
NSURLSession
Starting with iOS 7, Apple introduced NSURLSession. A sample implementation can be found here.
UIWebView
UIWebViews do not provide an API to implement certificate pinning, however an outgoing request can be intercepted with NSURLProtocol. Although complicated, sample code can be found here.
WKWebView
The more modern WKWebView supports certificate pinning, so is the recommended web view control to use (supported in iOS 8 and above).
Android < API 24
HttpUrlConnection
In older version of Android (prior to Android N/API 24) Certificate Pinning can be performed by using a custom TrustManager which uses a keystore containing the trusted certificates. The TrustManager is then used to create a new SSLSocketFactory to override the default from the HttpsURLConnection class.
A sample implementation can be found here.
WebView
WebView controls do not support certificate pinning, however workarounds do exist in some scenarios. For an example that allows pinning on GET requests, see a sample implementation here. Not that this implementation will not pin POST requests.
An alternative approach would be to make requests using HTTPClient or HttpURLConnection with Certificate Pinning and load the returned HTML into a webview. This approach would not work on pages that contains links or forms as subsequent requests would not be pinned.
CWAC-NetSecurity
CWAC-NetSecurity is a backport of the Network Security Configuration subsystem introduced in Android N and allows the same configuration files to be used in Android 4.2 and above and therefore certificate pinning can be performed as shown here. It should be noted that there are some limitations, such as cleartextTrafficPermitted being ignored when using HttpURLConnection.
OkHttp
The OkHttp library can provide certificate pinning via the CertificatePinner class. To pin against the certificate public key, a code example can be found here.
Android > API 24
Android N introduced the Network Security Configuration API allowing us to place the public key of the certificate (SubjectPublicKeyInfo) into the network_security_config.xml file that is referenced by the AndroidManfest.xml file. This will also provide pinning for WebViews. An example can be found here.