You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Great project but there is a weakness, how do we pin a SSL certificate? Otherwise anyone could just use Proxyman and do a man-in-the-middle attack to see what the app is sending out (such as api key etc)
I can use this code below with a normal URL connection and pin the certificate down like that. But how can I integrate this urlSession with swift-EventSource? I couldn't find a way yet...
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
// Helper function to check for subdomains
func containsSubdomain(host: String, subdomains: [String]) -> Bool {
// Split the host into components
let hostComponents = host.split(separator: ".")
// Ensure there are enough components to check for subdomain
guard hostComponents.count > 2 else { return false }
// The subdomain is the first component of the host
let subdomain = String(hostComponents[0])
// Check if the subdomain matches any of the given subdomains
return subdomains.contains(subdomain)
}
// Extract the host from the protection space
let host = challenge.protectionSpace.host
// Check if the current server type is not production
if Constants.currentServerType != .production {
// If not in production, bypass the certificate pinning check
LogService.shared.logInfo("Bypassing certificate pinning check for non-production server.")
completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))
return
}
// Proceed with certificate pinning check for production server
guard let serverTrust = challenge.protectionSpace.serverTrust else {
LogService.shared.logCritical("No server trust provided")
completionHandler(.cancelAuthenticationChallenge, nil)
return
}
var error: CFError?
guard SecTrustEvaluateWithError(serverTrust, &error) else {
if let cfError = error {
let nsError = cfError as Error as NSError
LogService.shared.logCritical("SecTrustEvaluateWithError failed.", nsError)
} else {
LogService.shared.logCritical("SecTrustEvaluateWithError failed.")
}
completionHandler(.cancelAuthenticationChallenge, nil)
return
}
guard let certificateChain = SecTrustCopyCertificateChain(serverTrust) as? [SecCertificate],
let serverCertificate = certificateChain.first else {
LogService.shared.logCritical("Failed to get server certificate from chain.")
completionHandler(.cancelAuthenticationChallenge, nil)
return
}
let serverCertificateData = SecCertificateCopyData(serverCertificate) as Data
let decryptedBase64Certificate = Keys.Global().apiCert
guard let localCertificateData = Data(base64Encoded: decryptedBase64Certificate) else {
LogService.shared.logCritical("Failed to decode local certificate from base64.")
completionHandler(.cancelAuthenticationChallenge, nil)
return
}
if serverCertificateData == localCertificateData {
LogService.shared.logInfo("Server certificate matches pinned certificate.")
let credential = URLCredential(trust: serverTrust)
completionHandler(.useCredential, credential)
return
} else {
LogService.shared.logCritical("Server certificate does not match pinned certificate.")
delegate?.didReceiveCertificateMismatchError() // Notify the delegate
}
completionHandler(.cancelAuthenticationChallenge, nil)
}
```
The text was updated successfully, but these errors were encountered:
Hi @houmie, thank you for posting. This repo is mainly intended for consumption in our other SDKs where certificate pinning is not required. We are always open to public contributions if you see a clean way to integrate pinning into the configuration. Another option is you fork the repo and perhaps tweak this region of the code.
Great project but there is a weakness, how do we pin a SSL certificate? Otherwise anyone could just use Proxyman and do a man-in-the-middle attack to see what the app is sending out (such as api key etc)
I can use this code below with a normal URL connection and pin the certificate down like that. But how can I integrate this urlSession with swift-EventSource? I couldn't find a way yet...
The text was updated successfully, but these errors were encountered: