Explore Library
Code Quiz

TLS Pinning Delegate Fallback Bug

Spot the subtle mistake that silently defeats certificate pinning in a URLSession delegate.

Codeswift
func urlSession(_ session: URLSession,
                didReceive challenge: URLAuthenticationChallenge,
                completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
    guard challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust,
          let serverTrust = challenge.protectionSpace.serverTrust,
          let cert = SecTrustGetCertificateAtIndex(serverTrust, 0) else {
        completionHandler(.cancelAuthenticationChallenge, nil)
        return
    }

    let remoteCertData = SecCertificateCopyData(cert) as Data
    let pinnedCertData = loadPinnedCertificate()

    if remoteCertData == pinnedCertData {
        completionHandler(.useCredential, URLCredential(trust: serverTrust))
    } else {
        completionHandler(.performDefaultHandling, nil)
    }
}

What is the security bug in this pinning implementation?