In Episode 5, we break down the mechanics of certificate pinning, the “Leaf vs. Root” debate, and how to implement a pinning strategy that secures your data without causing an operational disaster.
🔓Why System Trust Isn't Enough
When your app connects to api.yourcompany.com, iOS asks: “Is this certificate valid, and was it signed by a Certificate Authority (CA) that I trust?”
The vulnerability? Scope of trust.
If a hacker compromises any valid Certificate Authority, they can issue a fake certificate for your domain. Or if a user installs a custom Root Certificate on their device (think Charles Proxy), they can sign their own fake certificates.
iOS sees a valid signature chain and allows the connection.
Certificate Pinning changes the rules. Instead of saying “I trust any valid certificate,” your app says: “I only trust a certificate with this specific cryptographic signature.”
⚠️The Risk: How to Brick Your App
Imagine you build a healthcare app. You pin your server's Leaf Certificate—the specific certificate currently on your load balancer.
That certificate expires in 12 months. Eleven months later, your DevOps team updates the load balancer with a new certificate. They test it in the browser; it works perfectly.
But instantly, every installed instance of your iOS app stops working.
Why? Because your app is hard-coded to expect the old certificate's signature. The new one is valid, but it doesn't match the pin. The app rejects the connection as an attack.
And here's the worst part:
You cannot fix this on the server. You have to build a new version of the app with the new pin, submit it to the App Store, wait for review, and hope your users update.
This is the nightmare scenario. And it happens more often than you'd think.
🎯The Strategy: What Should You Pin?
You have three choices in the chain of trust:
1. The Leaf Certificate
The certificate at the bottom of the chain—the one assigned to your specific domain.
Pros: Tightest security
Cons: Changes frequently (sometimes every 90 days if you use Let's Encrypt)
Verdict: For most teams, do not pin the leaf. It's too brittle.
2. The Intermediate Certificate
The authority that signed your leaf.
Pros: Changes much less often—usually every few years
Cons: If your provider changes their intermediate structure, you still break
Verdict: Good balance for most apps
3. The Root Certificate
The top-level authority (like DigiCert Global Root).
Pros: Last for 10 to 20 years—very stable
Cons: You're trusting everything that Root signs
Verdict: Blocks local attacks (Charles Proxy) while minimizing maintenance
For most applications—health, enterprise, social—pinning the Intermediate or the Root is the sweet spot.
🔑Pin the Public Key, Not the Certificate
Never pin the certificate file itself. Pin the SPKI—the Subject Public Key Info.
The SPKI is the cryptographic heart of the certificate. If you rotate your certificate but generate it using the same private key, the SPKI hash remains the same.
This gives your DevOps team the freedom to renew certificates without breaking the mobile app, as long as they reuse the key.
🔒The Golden Rule: Always Have a Backup Pin
Never ship an app with just one trusted hash.
If that key is compromised, or if your cloud provider forces a sudden rotation, you're dead in the water.
You should always include:
- 1.The hash of your current active key
- 2.The hash of a backup key (a key pair you have generated and stored safely in a vault, ready to be deployed to your server in an emergency)
This is your “Break Glass” mechanism.
💻Implementation References
Official Documentation
📚 Apple Developer Documentation
- Handling an Authentication Challenge → How to implement URLSessionDelegate for server trust evaluation
- Evaluating a Trust and Parsing the Result → Using SecTrustEvaluateWithError to validate certificate chains
- Getting a Certificate's Public Key → Extracting the SPKI for hashing
- App Transport Security (ATS) → Understanding iOS's built-in TLS requirements
🔧 OWASP Reference
- OWASP Certificate and Public Key Pinning → Industry best practices and pinning strategies
Key Implementation Pattern
Certificate pinning on iOS follows this pattern:
- Implement
URLSessionDelegateand handleurlSession(_:didReceive:completionHandler:) - Check that
authenticationMethod == NSURLAuthenticationMethodServerTrust - Call
SecTrustEvaluateWithErrorto verify the chain against system CAs first - Extract the public key with
SecCertificateCopyKeyandSecKeyCopyExternalRepresentation - Hash the SPKI (SHA-256) and compare against your pinned hashes
- Call
completionHandler(.useCredential, ...)on match, or.cancelAuthenticationChallengeon failure
See Apple's "Handling an Authentication Challenge" documentation for complete sample code.
⚠️ Critical: Always Include a Backup Pin
Generate a backup key pair offline, store the private key securely, and include its public key hash in your app. If your primary certificate is compromised or rotated unexpectedly, this backup pin prevents a total lockout of your users.
✅Four Things You Can Do This Week
1. Evaluate if you need pinning
If you're working on a high-value app—handling health data, corporate secrets, or private messages—you should be evaluating pinning. If you're building a simple recipe app, standard HTTPS is likely enough.
2. If you implement pinning, choose the right level
Pin the Intermediate CA or Root CA, not the Leaf certificate. This balances security with uptime.
3. Pin the SPKI, not the certificate file
This allows certificate renewal without updating the app, provided the key stays the same.
4. Always include a backup pin
Generate a backup key pair, store it securely offline, and include its hash in your app. This is your emergency escape hatch.
🎯Key Takeaways
- 1.Pinning protects against interception—it ensures your app talks only to your server, not a proxy or an attacker.
- 2.Don't pin the Leaf—it changes too often. Pin the Intermediate CA or the Root CA to balance security with uptime.
- 3.Pin the Public Key (SPKI), not the file—this allows you to renew certificates without updating the app, provided the key stays the same.
- 4.Always ship a Backup Pin—without it, you're one server-side mistake away from a total outage.
📱About Sandboxed
Sandboxed is a podcast for people who actually ship iOS apps and care about how secure they are in the real world.
Each episode, we take one practical security topic — like secrets, auth, or hardening your build chain — and walk through how it really works on iOS, what can go wrong, and what you can do about it this week.
If that sounds like your kind of thing, subscribe to stay ahead of the quiet, boring changes that add up to real security wins.
Ready to dive deeper?
We've secured the device (Episode 4) and the transport tunnel (Episode 5). But once that request reaches your server... who is it? In Episode 6, we talk about Authentication: designing robust backend auth for mobile—beyond “Just use a JWT.”