datatheorem / TrustKit

Easy SSL pinning validation and reporting for iOS, macOS, tvOS and watchOS.
MIT License
2.02k stars 362 forks source link

App crashing if TrustKit swizzling is enabled #209

Closed thetminko closed 5 years ago

thetminko commented 5 years ago

Issue overview

App crash when using Firebase Auth and TrustKit with swizzling enabled. I have talked to Firebase people, and they suggest it could be TrustKit issue with GTMSessionFetcher. You can refer to the issue I created in Firebase Auth repo https://github.com/firebase/firebase-ios-sdk/issues/3742 I have also attached the sample project to reproduce. https://github.com/thetminko/FirebaseAuthTrustKit

Describe your environment

Xcode version: 10.3 (10G8) Firebase SDK version: 5.20.2, 6.2.2, 6.7.0 Firebase Component: Auth Component version: 5.20.2, 6.2.2, 6.7.0 TrustKit 1.6.2 [REQUIRED] Step 3: Describe the problem

Firebase Auth crashes when using TrustKit in the project with enabled swizzling

Steps to reproduce:

What happened? How can we make the problem occur? This could be a description, log/console output, etc.

Install Firebase/Auth and TrustKit using Cocoa Pods Init TrustKit with swizzling enabled Exec PhoneAuthProvider.provider().verifyPhoneNumber(...) App crash View my sample project https://github.com/thetminko/FirebaseAuthTrustKit

Console Logs:

2019-08-28 16:20:47.499384+0800 FirebaseAuthTrustKit[21828:4910670] === TrustKit: Proxy-ing NSURLSessionDelegate: GTMSessionFetcher 2019-08-28 16:20:47.499766+0800 FirebaseAuthTrustKit[21828:4910670] Fetcher delegate class: TSKNSURLSessionDelegateProxy 2019-08-28 16:20:47.500185+0800 FirebaseAuthTrustKit[21828:4910670] Fetcher made an extra session: GTMSessionFetcher 0x137a03400 2019-08-28 16:20:47.500357+0800 FirebaseAuthTrustKit[21828:4910670] Couldn't assign delegate. 2019-08-28 16:20:47.504906+0800 FirebaseAuthTrustKit[21828:4910670] Fetcher delegate class: TSKNSURLSessionDelegateProxy 2019-08-28 16:20:47.505126+0800 FirebaseAuthTrustKit[21828:4910670] -[GTMSessionFetcher setFetcher:forTask:]: unrecognized selector sent to instance 0x137a03400 2019-08-28 16:20:47.505945+0800 FirebaseAuthTrustKit[21828:4910670] Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[GTMSessionFetcher setFetcher:forTask:]: unrecognized selector sent to instance 0x137a03400' First throw call stack: (0x193e5a98c 0x1930339f8 0x193d771c8 0x193e601d4 0x193e61e6c 0x104e630c0 0x104e40df8 0x104e3d634 0x104defb80 0x104df2848 0x104df1eb4 0x104def444 0x104e13d5c 0x104dec9a8 0x104dec748 0x104de6324 0x105058c78 0x105067480 0x104de625c 0x104de5d34 0x193e62010 0x193d43be0 0x104e7b2e4 0x104e79f40 0x193d463c8 0x104e79d48 0x104e7b130 0x1050576f4 0x105058c78 0x1050666fc 0x193dec32c 0x193de7264 0x193de67c0 0x195fe779c 0x1c08e5c38 0x104dd9de4 0x1938aa8e0) libc++abi.dylib: terminating with uncaught exception of type NSException Stack Trace

thread #1, queue = 'com.google.firebase.auth.globalWorkQueue', stop reason = signal SIGABRT frame #0: 0x00000001939f70dc libsystem_kernel.dylibpthread_kill + 8 frame #1: 0x0000000193a749b0 libsystem_pthread.dylibpthread_kill$VARIANT$armv81 + 296 frame #2: 0x000000019394fea8 libsystem_c.dylibabort + 140 frame #3: 0x000000019301c788 libc++abi.dylibabort_message + 132 frame #4: 0x000000019301c934 libc++abi.dylibdefault_terminate_handler() + 308 frame #5: 0x0000000193033e00 libobjc.A.dylib_objc_terminate() + 124 frame #6: 0x0000000193028838 libc++abi.dylibstd::__terminate(void (*)()) + 16 frame #7: 0x00000001930288c4 libc++abi.dylibstd::terminate() + 84 frame #8: 0x0000000193033d5c libobjc.A.dylibobjc_terminate + 12 frame #9: 0x0000000105058c8c libdispatch.dylib_dispatch_client_callout + 36 frame #10: 0x0000000105067480 libdispatch.dylib`_dispatch_lane_barrier_sync_invoke_and_complete + 124 frame #11: 0x0000000104de625c FirebaseAuthTrustKit-[FIRAuth setAPNSToken:type:](self=0x0000000282735360, _cmd="setAPNSToken:type:", token=32 bytes, type=FIRAuthAPNSTokenTypeUnknown) at FIRAuth.m:1371:3 frame #12: 0x0000000104de5d34 FirebaseAuthTrustKit-[FIRAuth application:didRegisterForRemoteNotificationsWithDeviceToken:](self=0x0000000282735360, _cmd="application:didRegisterForRemoteNotificationsWithDeviceToken:", application=0x0000000135d02910, deviceToken=32 bytes) at FIRAuth.m:1336:3 frame #13: 0x0000000193e62010 CoreFoundationinvoking_ + 144 frame #14: 0x0000000193d43be0 CoreFoundation-[NSInvocation invoke] + 292 frame #15: 0x0000000104e7b2e4 FirebaseAuthTrustKit93-[GULAppDelegateSwizzler application:donor_didRegisterForRemoteNotificationsWithDeviceToken:]_block_invoke(.block_descriptor=0x000000016b02e8d0, interceptor=0x0000000282735360) at GULAppDelegateSwizzler.m:849:37 frame #16: 0x0000000104e79f40 FirebaseAuthTrustKit72+[GULAppDelegateSwizzler notifyInterceptorsWithMethodSelector:callback:]_block_invoke(.block_descriptor=0x000000016b02e830, key=@"GUL_0x282735360", obj=0x000000028142ef30, stop=NO) at GULAppDelegateSwizzler.m:680:7 frame #17: 0x0000000193d463c8 CoreFoundation-[NSFrozenDictionaryM enumerateKeysAndObjectsWithOptions:usingBlock:] + 176 frame #18: 0x0000000104e79d48 FirebaseAuthTrustKit+[GULAppDelegateSwizzler notifyInterceptorsWithMethodSelector:callback:](self=GULAppDelegateSwizzler, _cmd="notifyInterceptorsWithMethodSelector:callback:", methodSelector="application:didRegisterForRemoteNotificationsWithDeviceToken:", callback=0x0000000104e7b1c4) at GULAppDelegateSwizzler.m:667:3 frame #19: 0x0000000104e7b130 FirebaseAuthTrustKit-[GULAppDelegateSwizzler application:donor_didRegisterForRemoteNotificationsWithDeviceToken:](self=0x00000002816286e0, _cmd="application:didRegisterForRemoteNotificationsWithDeviceToken:", application=0x0000000135d02910, deviceToken=32 bytes) at GULAppDelegateSwizzler.m:840:3 frame #20: 0x00000001050576f4 libdispatch.dylib_dispatch_call_block_and_release + 24 frame #21: 0x0000000105058c78 libdispatch.dylib_dispatch_client_callout + 16 frame #22: 0x00000001050666fc libdispatch.dylib_dispatch_main_queue_callback_4CF + 1360 frame #23: 0x0000000193dec32c CoreFoundationCFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE + 12 frame #24: 0x0000000193de7264 CoreFoundation__CFRunLoopRun + 1924 frame #25: 0x0000000193de67c0 CoreFoundationCFRunLoopRunSpecific + 436 frame #26: 0x0000000195fe779c GraphicsServicesGSEventRunModal + 104 frame #27: 0x00000001c08e5c38 UIKitCoreUIApplicationMain + 212 frame #28: 0x0000000104dd9de4 FirebaseAuthTrustKitmain at AppDelegate.swift:14:7 frame #29: 0x00000001938aa8e0 libdyld.dylib`start + 4 Podfile

platform :ios, '10.0' target 'FirebaseAuthTrustKit' do pod 'Firebase/Auth', '~> 6.2.0' pod 'TrustKit', '~> 1.6.2' end

nabla-c0d3 commented 5 years ago

Hello, Thanks for the detailed bug report! It definitely looks like a bug when GTMSessionFetcher and TrustKit interact together. TrustKit with swizzling enabled is only meant to be used for fairly "simple" apps. In your case, it looks like the app is a bit more complex so I would advise turning off swizzling, and instead "manually" implementing pinning using a TSKPinningValidator. Swizzling is by design a pretty experimental/advanced feature and it's difficult for us to support all the potential use cases for it.

thetminko commented 5 years ago

@nabla-c0d3 Thanks for the suggestion to turn off swizzling. I had a use case where I could not turn off the swizzling. I understand that TrustKit will not be able support this issue, I will just close the ticket.