Search code examples
iossslafnetworkingpinning

Allow Connection For Invalid SSL Pinning on AFNetwroking


I'm trying to implement ssl pinning in our iOS app.

The definition as declared by our security architect was to implement it in 2 phases:
- 1st phase is to send an analytics event each time we recognise a bad pinning happening (if the pinning fails, I should send event, but allow the request to continue)
- 2nd phase is to actually block each call that doesn't successfully pass pinning.

We have 2 network layers in the app, one of them uses Alamofire, the other one is using AFNetworking. I'm successfully implemented phase 1 in the Alamofire based network layer. My issue is with the AFNetworking:

AFNetworking is blocking any call that fails the pinning, once a policy is set. Unfortunatly, I would like it to allow these calls.

I tried setting the policy's allowInvalidCertificates property to YES, which let all those failing pinning to continue as needed, but I'm not sure how can I be notified that a specific pinning was failed (in order to send the event)

Any help would be much appreciated.

UPDATE

So I figure out I can set a block to be called whenever a challenge is raised using:

- (void)setSessionDidReceiveAuthenticationChallengeBlock:(NSURLSessionAuthChallengeDisposition (^)(NSURLSession *session, NSURLAuthenticationChallenge *challenge, NSURLCredential * __autoreleasing *credential))block {

and/or

- (void)setTaskDidReceiveAuthenticationChallengeBlock:(NSURLSessionAuthChallengeDisposition (^)(NSURLSession *session, NSURLSessionTask *task, NSURLAuthenticationChallenge *challenge, NSURLCredential * __autoreleasing *credential))block {

This allow me to make the validations on the challenge, and for the 1st phase I could send the event and return NSURLSessionAuthChallengePerformDefaultHandling which is exactly what I need. For some reason, the task block is not being invoked no matter what I do, while the session block is.


Solution

  • So I figure out I can set a block to be called whenever a challenge is raised using:

    - (void)setSessionDidReceiveAuthenticationChallengeBlock:(NSURLSessionAuthChallengeDisposition (^)(NSURLSession *session, NSURLAuthenticationChallenge *challenge, NSURLCredential * __autoreleasing *credential))block {

    and/or

    - (void)setTaskDidReceiveAuthenticationChallengeBlock:(NSURLSessionAuthChallengeDisposition (^)(NSURLSession *session, NSURLSessionTask *task, NSURLAuthenticationChallenge *challenge, NSURLCredential * __autoreleasing *credential))block {

    This way I can get do whatever side effect needed (in my case, send event with relevant data) and decide if to block the request if needed or let it go on as no policy was configured...