# Info.plist based Certificate Pinning on iOS

In the past you might have used 3rd party libraries like [TrustKit](https://github.com/datatheorem/TrustKit) or [Alamofire](https://github.com/Alamofire/Alamofire) to protect your app from [man-in-the-middle attacks](https://www.raywenderlich.com/1484288-preventing-man-in-the-middle-attacks-in-ios-with-ssl-pinning) because those libraries support SSL public key pinning.

You might not know this but Apple introduced native support for SSL public key pinning in iOS 14 🥳

If you are not familiar with this native capability I recommend reading Apple's article [Identity Pinning: How to configure server certificates for your app](https://developer.apple.com/news/?id=g9ejcf8y). Here is a summary:

- You can specify a collection of certificates in your `Info.plist` that App Transport Security (ATS) expects when connecting to named domains.
- A pinned CA public key must appear in either an intermediate or root certificate in a certificate chain
- Pinned keys are always associated with a domain name, and the app will refuse to connect to that domain unless the pinning requirement is met.
- You can associate multiple public keys with a domain name.

This built-in pinning works well for `URLSession` but **does it work for all APIs on top of `CFNetwork`**?

The sad truth is **no**. 😔

`WKWebView` will still connect and load content from the domain if the SSL public key deviates from the one specified in `Info.plist`.

`SFSafariViewController` does not honor the settings in `Info.plist` as well. This behavior might be less surprising considering that `SFSafariViewController` [runs in a separate process](https://developer.apple.com/videos/play/wwdc2015-504/?time=494).

I tested those APIs on various releases, including the most recent iOS 15.4.

%[https://youtu.be/ZC0KpydbzWc]

You can verify my observation with a test app I open-sourced. 

%[https://github.com/MarcoEidinger/TestingNSPinnedDomains]

Apple's [answer is unsatisfying](https://developer.apple.com/forums/thread/681734) as it is not clear which APIs are expected to honor the certificates specified in `Info.plist`. 

I believe that SSL pinning based on `NSPinnedDomains` should work automatically with all CFNetwork based APIs like
- `URLSession`
- `WKWebView`.
- `SFSafariViewController`
- `ASWebAuthenticationSession`

Maybe one day.... 





