Parse-SDK-iOS-OSX icon indicating copy to clipboard operation
Parse-SDK-iOS-OSX copied to clipboard

How to add SSL Certificate pinning in Parse Configuration (Parse SDK iOS)

Open amitpristyn opened this issue 4 years ago • 10 comments

There is no option to add certificate pinning and verify can you please help

amitpristyn avatar Dec 29 '20 09:12 amitpristyn

This type of functionality could be added if you want to take on the task. My initial thoughts are you conform to the didReceiveChallenge delegate method here: https://github.com/parse-community/Parse-SDK-iOS-OSX/blob/5dad4f224d5ae4b36ead891acbdfc15b86d527ae/Parse/Parse/Internal/Commands/CommandRunner/URLSession/Session/PFURLSession.m#L236-L258

Then you need to pass the completionHandler block back through the SDK and expose it to the developer (like some of the other delegates are doing). The developer should handle the challenge, save certs through the Keychain, etc. They simply complete the handler with their desired choice.

cbaker6 avatar Jan 04 '21 20:01 cbaker6

This type of functionality could be added if you want to take on the task. My initial thoughts are you conform to the didReceiveChallenge delegate method here:

https://github.com/parse-community/Parse-SDK-iOS-OSX/blob/5dad4f224d5ae4b36ead891acbdfc15b86d527ae/Parse/Parse/Internal/Commands/CommandRunner/URLSession/Session/PFURLSession.m#L236-L258

Then you need to pass the completionHandler block back through the SDK and expose it to the developer (like some of the other delegates are doing). The developer should handle the challenge, save certs through the Keychain, etc. They simply complete the handler with their desired choice.

I don't know where I use this

please check my code given below

 class func setParserClientConfigAndInit() {
        
//        let session = URLSession(
//        configuration: URLSessionConfiguration.ephemeral,
//        delegate: URLSessionPinningDelegate(),
//        delegateQueue: nil)
        
        let configuration = ParseClientConfiguration {
            $0.applicationId = KAPI.applicationId
            $0.clientKey = ""
            $0.server = KAPI.applicationServer
            $0.urlSessionConfiguration.httpAdditionalHeaders = setParseHeader()
            #if DEBUG
            // not used
            #else
//            $0.urlSessionConfiguration = session.configuration
            #endif
        }
        
        //Parse initilize
        Parse.initialize(with: configuration)
        
    }

I don't know where I pass or where I use it on the given

    class NSURLSessionPinningDelegate: NSObject, URLSessionDelegate {

    func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Swift.Void) {

        // Adapted from OWASP https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#iOS

        if (challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) {
            if let serverTrust = challenge.protectionSpace.serverTrust {
                let isServerTrusted = SecTrustEvaluateWithError(serverTrust, nil)

                if(isServerTrusted) {
                    if let serverCertificate = SecTrustGetCertificateAtIndex(serverTrust, 0) {
                        let serverCertificateData = SecCertificateCopyData(serverCertificate)
                        let data = CFDataGetBytePtr(serverCertificateData);
                        let size = CFDataGetLength(serverCertificateData);
                        let cert1 = NSData(bytes: data, length: size)
                        let file_der = Bundle.main.path(forResource: "certificateFile", ofType: "der")

                        if let file = file_der {
                            if let cert2 = NSData(contentsOfFile: file) {
                                if cert1.isEqual(to: cert2 as Data) {
                                    completionHandler(URLSession.AuthChallengeDisposition.useCredential, URLCredential(trust:serverTrust))
                                    return
                                }
                            }
                        }
                    }
                }
            }
        }

        // Pinning failed
        completionHandler(URLSession.AuthChallengeDisposition.cancelAuthenticationChallenge, nil)
    }

}

amitpristyn avatar Jan 05 '21 10:01 amitpristyn

You have the right idea, but the code you listed is what you would use as a developer. You need to open a PR, add the delegate method I mentioned and add the new configuration parameter. You can use what I did in ParseSwift as a reference https://github.com/parse-community/Parse-Swift/pull/45/files Though the structure is different.

cbaker6 avatar Jan 05 '21 13:01 cbaker6

You will also need to do more If you want to pass in your own headers. You won't be able to use your own delegate because Parse already has one. You should only need to respond to the challenge and maybe pass in headers which can be two different parameters that can be passed into the config assuming you add the capability to the SDK.

cbaker6 avatar Jan 05 '21 17:01 cbaker6

You will also need to do more If you want to pass in your own headers. You won't be able to use your own delegate because Parse already has one. You should only need to respond to the challenge and maybe pass in headers which can be two different parameters that can be passed into the config assuming you add the capability to the SDK.

Any method to add SSL pinning certificate in parse request and response handle like an error in parse query

amitpristyn avatar Jan 05 '21 17:01 amitpristyn

You will also need to do more If you want to pass in your own headers. You won't be able to use your own delegate because Parse already has one. You should only need to respond to the challenge and maybe pass in headers which can be two different parameters that can be passed into the config assuming you add the capability to the SDK.

Any method to add SSL pinning certificate in parse request and response handle like an error in parse query

I am working as an iOS developer and I don't know how to add a certificate in Parse initialization SDK because for security purpose any middle attack all data is exposed in front of Charles or any other so the client requirement is to add a certificate in parse request

in Android, it is used in request but no any option in iOS SWIFT

amitpristyn avatar Jan 05 '21 17:01 amitpristyn

The links and comments I posted are in reference to how to do it. iOS allows it via URLSession, the iOS SDK uses URLSession, but currently doesn't expose what's needed to enable this for Parse. You can use what I posted for direction on how to add the feature to the iOS SDK for everyone to use, but you have to modify the SDK itself to expose what's needed. There's no way I know of jumping in front of the dedicated URLSession Parse uses to intercept authentication challenges. The Parse URLSession is doing a ton of things, adding the feature will also allow it to authenticate

cbaker6 avatar Jan 05 '21 17:01 cbaker6

dup #1103

cbaker6 avatar Jan 21 '21 05:01 cbaker6

#1598 Here we have implemented the SSL pinning for our application. This is still not ready for PR - need to add some tests and documentation.

gytiskv avatar Jan 25 '21 11:01 gytiskv

This issue has been automatically marked as stale because it has not had recent activity. If you believe it should stay open, please let us know! As always, we encourage contributions, check out the Contributing Guide

stale[bot] avatar Jul 21 '21 01:07 stale[bot]