DZone - Securing Mobile Apps With Certificate Pinning
DZone - Securing Mobile Apps With Certificate Pinning
DZone - Securing Mobile Apps With Certificate Pinning
CONTENTS
ö ö MiTM Attacks
ö ö Types of Certificates
ö ö Countering Objections
ö ö Conclusion
WRITTEN BY RONO DASGUPTA
MOBILE SECURITY ANALYST, NOWSECURE
need to be in the same room or even on the same network. For example,
MiTM Attacks
As virtually all mobile apps communicate with backend systems that a virtual private network (VPN) provider could force users to install and
require secure network communications, mobile app developers should trust a malicious root certificate on their devices to gain full access to
adopt best practices for secure architectural design and coding techniques. decrypt network communication.
Man-in-the-middle (MiTM) attacks are essentially a form of digital Hackers can carry out MiTM attacks in many ways, such as using
eavesdropping that exploit a weakness in network communication. They misconfigured self-signed certificates with weak private keys, fake Wi-Fi
occur when a malicious third party gets between a user's mobile app and login portals, e-mail attachments, and free VPNs.
the backend server the device attempts to communicate with. The threat
HOW MITM ATTACKS ENSNARE USERS
actor can intercept, read, and alter data sent between the two parties. Thanks to social engineering and phishing, some users can easily be
convinced to make changes to their mobile devices to make them
And worse, a variety of different kinds of MiTM attacks means developers
susceptible to a man-in-the-middle attack. The attacker’s weapon of
must use multiple techniques to protect their apps. But it's fairly easy for
choice is a malicious iOS profile or Android certificate.
developers to take a few coding measures to guard against these threats.
All mobile app developers should use HTTPS for secure communication.
MiTM attacks, however, present tremendous risk to a mobile app user's
personal data because they nullify the confidentiality and integrity
provided by HTTPS.
1
SECURING MOBILE APPS WITH CERT PINNING
with a name similar to the legitimate access point. After being redirected On the iOS device, you can see that the profile — in this case — is
to a captive portal that looks authentic, the user is instructed to marked “not signed,” but an attacker can easily sign the profile using a
download and install a device profile. A captive portal web page requires code-signing certificate.
a user to enter information or accept terms after connecting with a Wi-Fi
The malicious profile presented to the user contains a self-signed
network before being granted access. These are commonly seen at
certificate. The certificate needs to be self-signed for the device to install
coffee shops, hotels, and airports.
it as a root CA. Clicking on “Install” takes the user to a page that warns
If a victim ignores vague and innocuous security warnings and installs the user that installing the certificate will add it to the list of trusted
the profile, the attacker gains access to network traffic and can decrypt certificates on their device (see screenshot below). This warning clearly
nearly everything sent and received by the mobile device. fails to convey the actual danger of installing the certificate — that
network traffic could be compromised.
IOS ATTACKS WITH MALICIOUS PROFILES
On iPhones, iOS profiles enable the creation of configuration settings
on the device. Network administrators commonly use this method
to efficiently set up secure Wi-Fi access or VPNs on employee devices.
Apple makes it easy to build custom iOS profiles with the free Apple
Configurator 2.
• Proxy settings Once a user installs the profile, which adds the certificate to a device’s
list of trusted certificates, an attacker that is able to redirect all network
• VPN settings
traffic through their proxy can basically decrypt all the HTTPS traffic sent
Here’s a screenshot of Apple Configurator 2’s UI: and received by the device. From the attacker’s perspective, carrying out
this kind of MiTM attack required very little time or effort.
App developers can choose to let their apps work with manually added
CA certificates, but they must understand the security ramifications of
doing so. Also note that Android P only supports HTTPS for all network
communication by default. Any HTTP endpoints must be explicitly
defined in the Network Security Configuration file.
Android and iOS devices are shipped with a default list of trusted
However, an attacker could leverage more sophisticated MiTM Pinning to an intermediate certificate is a step down in the hierarchy
techniques. For example, users could be convinced to install a from the root certificate mentioned above, but has similar problems.
malicious root certificate on their devices using phishing techniques The certificates at the bottom of the chain of trust — leaf certificates
or the hacker could compromise a certificate authority itself. While the — can be signed using an intermediate certificate. In that event, a
latter is difficult, getting a user to install a malicious root certificate malicious individual can procure a certificate for the domain in question
can be surprisingly simple. When a user trusts a certificate, the device signed by an intermediate certificate and hijack the connection because
alert doesn't convey the actual danger and many users simply click to his certificate will be trusted by the app.
accept as a force of habit.
Finally, pinning the public key of the actual leaf certificate is the best
Certificate pinning was originally developed to protect web and mobile option and we recommend choosing this over the other methods. Every
apps from rogue certificate authorities. Pinning ensures that no network certificate includes a public key associated with the private key, which
data is compromised even if a user is tricked into installing a malicious can be pinned within the app. This approach ensures the app trusts only
root certificate on their mobile device. Any app that pins its certificates signed certificates that an attacker cannot spoof.
would thwart such phishing attempts by refusing to transmit data over a
Some people complain that the above method makes rotating expired
compromised connection.
keys a hassle and are tempted to take shortcuts like pinning to CA rather
Launching an MiTM attack by bypassing certificate pinning is a very than leaf or avoiding cert pinning altogether. However, there are ways to
complex client-side procedure. An attacker would first need physical properly implement a certificate rotation without having to release new
access to the targeted mobile device and app. From there, he or she versions of the app when certs expire and need to be swapped out.
would need to root or jailbreak the device and reverse engineer, modify,
and rewrite the functions performing cert pinning in the app. In the end,
bypassing certificate pinning is much more difficult than executing the
type of attacks certificate pinning guards against.
As part of good coding hygiene, all Android and iOS developers should
implement certificate pinning for apps that handle sensitive data as a
countermeasure against MiTM attacks. This minimal degree of additional
effort yields significant protection. However, developers must be sure to
implement pinning correctly so they're not left with a false sense of security.
Cert pinning is imperative for any mobile app that exchanges sensitive
data like credentials, financial information, business transactions, and
PII. This includes mobile apps such as banking, healthcare, retail, utility,
automotive, ERP/CRM, and IoT. In short, this encompasses most apps To rotate certificates without any interruption in service, use cert pinning
that do anything more than surface public data. based on the modulus of the public key. This represents a unique
identifier for the private key. Compare the public key modulus and the </pin-set>
private key modulus to ensure the app trusts the proper certificate (or </domain-config>
Cert pinning using the modulus allows you to renew the public key You can use a number of third-party libraries to implement certificate
and swap it out as long as the private key doesn't change. Include two pinning in your Android apps. The popular Android library OkHttp is
modulus signatures in the app — one for active use and one for one for widely used for this purpose through its CertificatePinner class. The
future use with the private key stored offline. The following OpenSSL next three code snippets from the OkHttp website illustrate the process.
commands can be used in the terminal to check the modulus of the cert,
String hostname = "<domainname.com>";
depending on the cert extension (.pem, .cer, .crt, .der): CertificatePinner certificatePinner = new
CertificatePinner.Builder()
openssl x509 -in cert.pem -text -noout .add(hostname, "sha256/AAAAAAAAAAAAAAAAAAAAAAAA
openssl x509 -in cert.cer -text -noout AAAAAAAAAAAAAAAAAAA=")
openssl x509 -in cert.crt -text -noout .build();
openssl x509 -in certificate.der -inform der -text -noout OkHttpClient client = OkHttpClient.Builder()
.certificatePinner(certificatePinner)
Implementing Cert Pinning on iOS and Android .build();
Pinning the public key of the leaf certificate is generally the best
Request request = new Request.Builder()
approach because it's easy to manage when the server certificates
.url("https://" + hostname)
change. To do this, pin the leaf certificate based on the modulus of its
.build();
public key, which represents a unique identifier for the private key. client.newCall(request).execute();
Comparing the public key modulus and the private key modulus enables The code snippet above deliberately includes a false SHA256 hash value to
you to ensure the app trusts the correct certificate (or, more importantly, simulate a broken configuration, so it will throw an exception (the output
doesn't trust any other certificates). Pinning using the modulus allows shown in the snippet below). Looking at the output, you can find your
you to renew the public key and swap it out as long as the private key server keys if you don't already know them. The SHA256 hashes in the
doesn't change. Include two modulus signatures in the app — one for resulting output are for your server certificates' public keys.
active use and for future use, with the private key stored offline.
javax.net.ssl.SSLPeerUnverifiedException: Certificate
ANDROID pinning failure!
Manual methods for deploying certificate pinning on Android apps Peer certificate chain:
include making HttpsURLConnection only trust a certain set of CAs. For sha256/afwiKY3RxoMmLkuRW1l7QsPZTJPwDS2pdDROQjXw8ig=:
CN=mobile.myco.com, OU=PositiveSSL
more detail about this manual method, see the OWASP Certificate and
sha256/klO23nT2ehFDXCfx3eHTDRESMz3asj1muO+4aIdjiuY=
Public Key Pinning Technical Guide.
: CN=COMODO RSA Secure Server CA
sha256/grX4Ta9HpZx6tSHkmCrvpApTQGo67CYDnvprLg5yRME=
The Android Developer website describes a newer technique for
: CN=COMODO RSA Certification Authority
certificate pinning on Android, which involves providing hashes of
sha256/
certificates' public keys along with backup keys in an app's res/xml/ lCppFqbkrlJ3EcVFAkeip0+44VaoJUymbnOaEUk7tEU=: CN=Add
network_security_config.xml file. Backup keys help maintain app usage Trust External CA
if and when the CA being pinned or the keys themselves have to be Root
changed for some reason. If you don't include backup keys, you will be Pinned certificates for publicobject.com:
sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
forced to update your app in such cases.
at okhttp3.CertificatePinner.check(CertificatePinner.
The following snippet from the Android Developer site shows the res/ java)
at okhttp3.Connection.upgradeToTls(Connection.java)
xml/network_security_config.xml file.
at okhttp3.Connection.connect(Connection.java)
<?xml version="1.0" encoding="utf-8"?> at okhttp3.Connection.connectAndSetOwner(Connection.
<network-security-config> java)
<domain-config>
You will need to paste those SHA256 hashes into the CertificatePinner
<domain includeSubdomains="true">example.com</domain>
configuration as shown here:
<pin-set expiration="2018-12-17">
<pin digest="SHA-256">7HIpactkIAq2Y49orFOOQKur CertificatePinner certificatePinner = new
WxmmSFZhBCoQYcRhJ3Y=</pin> CertificatePinner.Builder()
<!-- backup pin --> .add(“mobile.myco.com”, “sha256afwiKY3RxoMmLkuRW1l7Q
<pin digest="SHA-256">fwza0LRMXouZHRC8Ei+4Pyul sPZTJPwDS2pdDROQjXw8ig=”)
dPRcf3UKgO/04cDM1oE=</pin> .add(“mobile.myco.com”, “sha256klO23nT2ehFDXCfx3eHTD
RESMz3asj1muO+4aIdjiuY=”) Once a proxy is installed as a root CA, it essentially acts as an MiTM and
.add(“mobile.myco.com”, “sha256grX4Ta9HpZx6tSHkmCrvp can intercept, decrypt, and modify all HTTPS communications between
ApTQGo67CYDnvprLg5yRME=”) the device, the mobile app, and backend servers.
.add(“mobile.myco.com”, “sha256lCppFqbkrlJ3EcVFAkeip
0+44RaoJUymbnOaEUk7tEU=”) If the proxy successfully intercepts traffic while you interact with the
.build(); mobile app during testing, that's a sure sign that certificate pinning isn't
enabled. If you believe you've properly implemented certificate pinning
IOS
but the proxy still intercepts your app's network data, a deeper dive into
On iOS, certificate pinning can be achieved through a
the app source code may be necessary to determine the problem.
NSURLConnectionDelegate using NSURLConnection. See the OWASP
Certificate and Public Key Pinning Technical Guide for more details Given the complexity of using OSS tools to test cert pinning, devs without
about this method. a network security background can turn to security analysts to do the
work or use an automated mobile app security testing tool. While you may
Other third-party libraries that help with certificate pinning on iOS apps
be using static analysis security testing tools (SAST) to automatically scan
include Alamofire and AFNetworking.
your source, they don't test for MiTM attacks — so you will need to add
AFNetworking offers a simple way of adding certificate pinning to mobile dynamic application security testing tools (DAST) that include cert pinning
apps. The following snippet can be used to pin one specific certificate of tests in order to properly test for MiTM attacks.
type "cer" from a given bundle. The method below can be called in an
The most effective way to check your work and ensure the mobile
init method to ensure that the app rejects all other certs apart from the
apps you develop are not vulnerable to MiTM attacks and are using
one pinned.
cert pinning properly is to integrate application security testing (DAST)
func certSecPolicy() { directly into the DevOps pipeline to security test every build, every
let securityPolicy = AFSecurityPolicy(pinningMode: day. Certain advanced automated security testing plug-ins for CI/CD
AFSSLPinningMode.Certificate)
platforms can enable continuous security testing for cert pinning. By
let certPath = NSBundle.mainBundle().
using automated tools, developers can skip the testing complexity and
pathForResource("pinnedcert", ofType: "cer")!
focus on their code.
let certContents = NSData(contentsOfFile: certPath)!
securityPolicy.pinnedCertificates = [certContents];
securityPolicy.validatesCertificateChain = false; Countering Objections
self.securityPolicy = securityPolicy
Some developers are reluctant to implement cert pinning and may
must remain static across all new certificates. In addition, backup keys Implementing cert pinning in your mobile app can strengthen the security
should always be added to the pinning configuration to maintain app of its network communications and is a big step in protecting your app
connectivity at all times. data. Once you invest in cert pinning, test to ensure that you have properly
implemented cert pinning to prevent MiTM attacks. While not crucial for
Developers may think that their apps don't transmit sensitive data. But
every mobile app out there, this measure is critical for any app at that
is that really the case and are they absolutely sure? Does your app have
contains high-risk, sensitive data and transactions.
login credentials, or account numbers, or PII? Nearly every app does,
so nearly every app should take cert pinning seriously. A mistake that
leads to data loss could be costly in terms of loss to a company's data
and reputation. Others complain that pinning impedes performance, but
benchmarks show that it's comparable to any form of encryption and
secure network transport. Others may note that their app doesn't use
SSL/TLS. This is an even bigger mistake, as all network communications
for any app should be encrypted.
Conclusion
As developers seek to build their next great mobile app, there are many
security coding best practices to take into account. Proper network
security with cert pinning should be very high on that list. While taking
the above actions to implement cert pinning may require some extra time
to develop, the effort will pay significant dividends. Securing network
communications to guard against MiTM exploits protects your mobile app
users, your data, and your business reputation.
Devada, Inc.
600 Park Offices Drive
Suite 150
Research Triangle Park, NC