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. Here is a summary:
- You can specify a collection of certificates in your
Info.plistthat 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
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
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.
I tested those APIs on various releases, including the most recent iOS 15.4.
You can verify my observation with a test app I open-sourced.
Apple's answer is unsatisfying as it is not clear which APIs are expected to honor the certificates specified in
I believe that SSL pinning based on
NSPinnedDomains should work automatically with all CFNetwork based APIs like
Maybe one day....