silkimen / cordova-plugin-advanced-http

Cordova / Phonegap plugin for communicating with HTTP servers. Allows for SSL pinning!
MIT License
400 stars 321 forks source link

[Bug] [iOS] self.pinnedCertificates is nil after a while #351

Open ir2pid opened 4 years ago

ir2pid commented 4 years ago

We get crashes on out iOS app

System info

Are you using ionic-native-wrapper?

Minimum viable code to reproduce

App crashes when pinning for a while. We see the self->pinnedCertificate is nil

Regular case image

When crashes self->pinningCertificates is nil image

Adza93 commented 4 years ago

Also experiencing same problem. On latest implementation in can sometimes happen in correlation with following issue:

Crashed: NSOperationQueue 0x104933860 (QOS: UNSPECIFIED) EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x00000005622d4490 0 libobjc.A.dylib objc_msgSend + 20 1 AFSecurityPolicy.m - Line 282 -[AFSecurityPolicy evaluateServerTrust:forDomain:] + 282 2 CordovaHttpPlugin.m - Line 52 __45-[CordovaHttpPlugin setupAuthChallengeBlock:]_block_invoke + 52 3 AFURLSessionManager.m - Line 970 -[AFURLSessionManager URLSession:didReceiveChallenge:completionHandler:] + 970

Anyone has any idea?

silkimen commented 4 years ago

Hi guys, I've tried to reproduce your problem on my device but this problem never occurred here. How long does the App run before this problem comes up? Is there anything special with your devices? Honestly, I've no idea where to start diagnosing this problem.

Adza93 commented 4 years ago

Hey there @silkimen! Thanks for your efforts. This is very very hard to reproduce. I got some feeling that this is happening very rarely when you start the application. It happens more when you put your app in background, then start to use it again after 10-30 min or more.

While using older SSL plugin,specifically its native part, I have called setSSLCertMode every time prior to establishing http connection, to ensure that connection will be according to request (pinned or not).

What I also discovered is that while you have changed implementation from setSSLCertMode to setServerTrustMode, this was not implemented on node part for ionic 3. Since ionic 3 is still very popular and stabile version of ionic, can you implement changes to this method?

I am almost sure there is something about calling this new method setServerTrustMode too often. For same action inside application that initiated 3, or 4 async request, it can happen now with new request that application crashes as described in issue ticket. Last version of @ionic-native/http I can find is 4.20.0 (for ionic 3 support).

Since I could not call setServerTrustMode directly, I use cordova wrapper like this:

declare var cordova; ....

public setServerTrustMode(mode): Promise { return new Promise((resolve, reject) => { try { cordova.plugin.http.setServerTrustMode(mode, () => { console.log('setServerTrustMode: success!'); resolve("OK"); }, function () { console.log('setServerTrustMode: error!'); reject("ERROR"); }); } catch (error) { console.warn("CordovaHttpPlugin called but 'cordova' is not defined. Probably this page is not opened with cordova view", error); reject("ERROR"); } }); }

I suspect this should work (it is not pretty but it should work.) when I debug native code I see that method setServerTrustMode is being called correctly. Its just that sometimes it crashes. That somethime is quite often if you release with latest version on production.

Hopefully this could help you get to bottom of this problem. Please say if I can be of any more help!

silkimen commented 4 years ago

Hi @Adza93,

thanks for your detailed problem description. I've never tried to reproduce with multiple calls of 'setServerTrustMode()'. Maybe this will do the trick.

It happens more when you put your app in background, then start to use it again after 10-30 min or more.

Seems like something is going wrong during NSCoder decoding, but I've no idea why.

I suspect this should work (it is not pretty but it should work.) when I debug native code I see that method setServerTrustMode is being called correctly.

There is absolutely no problem with your wrapper code. It's basically the same in ionic-native wrapper.

What I also discovered is that while you have changed implementation from setSSLCertMode to setServerTrustMode, this was not implemented on node part for ionic 3. Since ionic 3 is still very popular and stabile version of ionic, can you implement changes to this method?

Please open a new issue in the ionic-native repo for this request. This repo is just about the plugin itself, not about the ionic wrapper. Maybe someone else will implement missing features... maybe I'll do it myself if I find some time 😉

gummibjorn commented 3 years ago

We were actually able to reproduce this crash. It happens when you call setServerTrustMode during an ongoing Http-Call. In our case we called setServerTrustMode before every Request, so this happened quite frequently. After moving setServerTrustMode to the application start the crash seemed not to be reproducible anymore.

winnievips commented 6 months ago
Screenshot 2024-04-08 at 2 55 26 PM

Hihi, Anyone fixes for this yet? I'm still getting a lot of these crash logs for iOS devices but I am unable to replicate in my simulator / my device.

rokanraja1 commented 1 week ago

static NSArray AFCertificateTrustChainForServerTrust(SecTrustRef serverTrust) { CFIndex certificateCount = SecTrustGetCertificateCount(serverTrust); NSMutableArray trustChain = [NSMutableArray arrayWithCapacity:(NSUInteger)certificateCount]; @try { for (CFIndex i = 0; i < certificateCount; i++) { SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, i); if (certificate != NULL) { NSData certData = (__bridge_transfer NSData )SecCertificateCopyData(certificate); if (certData) { [trustChain addObject:certData]; } } } } @catch (NSException *exception) { NSLog(@"Error retrieving certificate data: %@", exception); return nil; }

return [NSArray arrayWithArray:trustChain];

} Solution for this issue