What is SSL Pinning?
SSL pinning is a technique used in a mobile application to verify that an endpoint the app is calling is using the expected certificate. Its purpose is to detect "man in the middle" attacks where a threat actor simulates your server and inspects the communications between the mobile application and the real server in order to harvest credentials or private information.
The process of SSL pinning involves using a plugin that is used for all HTTPS calls and will check the certificate presented by the endpoint and compare it to the one you have embedded with your application.
The most common plugin used for this is cordova-plugin-advanced-http. There are a few quirks with getting this plugin working with a Capacitor project which are detailed below.
One quirk is that Cordova projects output to the www folder whereas Capacitor ones use the public folder and this plugin (as of v3.3.0) expects certificates in the www folder (a PR to handle this is outstanding).
Why use SSL Pinning?
This technique is a best practice as defined through the OWASP Mobile Application Security guide. The specific guideline is MSTG-NETWORK-3 and if you have your mobile application penetration tested it is likely to be flagged as a vulnerability if your application does not "verifies the X.509 certificate of the remote endpoint".
The technique is a part of a layered approach to security and a defense against a "man in the middle" attack.
Sample Application
Here's the sample project provided for SSL pinning in a Capacitor application:
https://github.com/dtarnawsky/cs-ssl-pinning
Supplying certificates
Certificates need to be stored in thewww/certificates
folder. One way to ensure this is to create acertificates
folder undersrc
and then add this to theassets
property ofangular.json
:
{
"glob": "**/*.cer",
"input": "src/certificates",
"output": "certificates"
},
- The certificate must have a
.cer
extension. - Certificates must be in
DER
format.
Extract certificates via Browser
To extract the DER for a certificate:
- Visit the URL in a browser (Microsoft Edge)
- Click the lock symbol next to the URL
- Click the "Connection is Secure" link
- Click the certificate symbol next to the close button
- Click the details tab
- Click one of the certificates in the hierarchy
- Click Export button
- Choose "DER-encoded binary, single certificate" as the format
- Save the file to your certificates folder with an extension of .cer
- Repeat these steps for each certificate in the chain (that you want to check)
Extracting Certs with Open SSL
This sample app connects tohttps://mysafeinfo.com
. To extract the public certificates we can call:openssl s_client -connect mysafeinfo.com:443 -showcerts
- From the output of the command, create a new file in
/certificates
(name it .pem) - Paste into it all certificates shown in the output.
- Certificates start with the line
-----BEGIN CERTIFICATE-----
and end with the line-----END CERTIFICATE-----
(inclusive). - If multiple are shown, paste them in the order you see them in the output.
- Then convert to DER format
- eg.
openssl x509 -outform der -in <anything>.pem -out <anything>.cer
Check your Certificate
To validate if your.cer
file is in the right format (DER) you can run this command:openssl x509 -in <anything>.cer -inform der -text -noout
If it throws an errorunable to load certificate
then you know your file is using an incorrect format
Gotchas
- In iOS 13 additional requirements were added to TLS certificates. These can cause an SSL failure. Read about it here
- Using OpenSSL to extract all certificates in a chain can be a challenge and may not export every certificate. You may need to export from a browser
Comments
0 comments
Please sign in to leave a comment.