Best way to prevent a Man-in-the-middle attack in iOS

I'm trying to figure out the best way to prevent a Man-in-the-middle attack.
I see a lot of information about SSL Pinning,
But there are a lot of downsides to the pinning solutions.
I see another solution called Certificate Transparency (CT), Which is most common in browsers.
I made a test project and CT protocol using NSRequiresCertificateTransparency works as expected without any downsides,
But maybe I am missing something.
I'm wondering what is the best solution in iOS SSL Pinning or CT?
Thanks

I'm trying to figure out the best way to prevent a Man-in-the-middle attack.

Great question.

I see a lot of information about SSL Pinning,
But there are a lot of downsides to the pinning solutions.

Right you are. Certificate Pinning is great if you know that you are only ever going to connect to a finite set of servers. I suspect that this is what you are eluding to, in regards to "downsides." So if you have an easy way to distribute and rotate certificate data easily then this would be an option.

Regarding:

I made a test project and CT protocol using NSRequiresCertificateTransparency works as
expected without any downsides,
But maybe I am missing something.

Right, Certificate Transparency is great tool for verifying that a provided leaf does contain a set of SCTs (Signed Certificate Timestamp) either embedded in the certificate (RFC 6962), through a TLS extension (which can be seen in a Packet Trace), or by checking the OCSP logs of the certificate. When you make a trust decision in your app, I would recommend taking a look at is property via the SecPolicyRef object. Something like:

Code Block Objective-c
CFDictionaryRef evaluationDetailsRef = SecTrustCopyResult(serverTrust);
NSDictionary *evaluationDetails = (__bridge NSDictionary *)evaluationDetailsRef;
/* Take a look at evaluationDetails[(NSString *)kSecTrustCertificateTransparency] */

Should get you started.

Another technique to look at is evaluating the HEX serial number that can be extracted from SecCertificateCopySerialNumberData. The reason that this is important is because this is a unique identifier for a certificate and if you know the HEX serial number you can evaluate that the presenting leaf being provided from the Server is one that you expect.

Lastly, if your infrastructure support it, I would look into encrypted SNI as a TLS extension. This is a fairly new extension, but what it will do is make sure that a passive observing node in the middle of the your client and the server cannot intercept the hostname from the client hello and try to craft an impersonating certificate with a matching Common Name. The ESNI hides this while in transit.


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
Best way to prevent a Man-in-the-middle attack in iOS
 
 
Q