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?