Sandboxed – iOS Security for Builders

Episode 5

📌 Certificate Pinning: Your Safety Net or Your Worst Nightmare?

Certificate pinning prevents attackers from intercepting your traffic, even if they compromise a Certificate Authority. But do it wrong, and you'll brick your app for every single user.

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. 1.The hash of your current active key
  2. 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

🔧 OWASP Reference

Key Implementation Pattern

Certificate pinning on iOS follows this pattern:

  1. Implement URLSessionDelegate and handle urlSession(_:didReceive:completionHandler:)
  2. Check that authenticationMethod == NSURLAuthenticationMethodServerTrust
  3. Call SecTrustEvaluateWithError to verify the chain against system CAs first
  4. Extract the public key with SecCertificateCopyKey andSecKeyCopyExternalRepresentation
  5. Hash the SPKI (SHA-256) and compare against your pinned hashes
  6. Call completionHandler(.useCredential, ...) on match, or .cancelAuthenticationChallenge on 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.”

Stay in the Loop

Get iOS security insights, new episode alerts, and exclusive content delivered to your inbox.

No spam. Unsubscribe anytime.

Certificate Pinning: Your Safety Net or Your Worst Nightmare? | Sandboxed Podcast