Skip to content

MASTG-DEMO-0154: URLSessionDelegate Accepting Any Server Certificate

Download MASTG-DEMO-0154 IPA Open MASTG-DEMO-0154 Folder Build MASTG-DEMO-0154 IPA

Sample

The code below implements two URLSessionDelegate classes that both connect to expired.badssl.com. InsecureURLSessionDelegate calls completionHandler(.useCredential, URLCredential(trust: serverTrust)) without first calling SecTrustEvaluateWithError, accepting the expired certificate. SecureURLSessionDelegate correctly calls SecTrustEvaluateWithError and rejects the connection when trust evaluation fails.

MastgTest.swift
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import Foundation

// SUMMARY: Demonstrates both insecure (bypass) and secure (correct) URLSessionDelegate implementations
// connecting to expired.badssl.com. The insecure delegate accepts the expired certificate without
// evaluating trust; the secure delegate correctly rejects it via SecTrustEvaluateWithError.

class InsecureURLSessionDelegate: NSObject, URLSessionDelegate {
    // FAIL: [MASTG-TEST-0396] Accepts any certificate without evaluating server trust
    func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge,
                    completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        guard let serverTrust = challenge.protectionSpace.serverTrust else {
            completionHandler(.cancelAuthenticationChallenge, nil)
            return
        }
        // Insecure: creates a credential from serverTrust without calling SecTrustEvaluateWithError.
        completionHandler(.useCredential, URLCredential(trust: serverTrust))
    }
}

class SecureURLSessionDelegate: NSObject, URLSessionDelegate {
    // PASS: Correctly evaluates server trust before accepting the credential
    func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge,
                    completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        guard challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust,
              let serverTrust = challenge.protectionSpace.serverTrust else {
            completionHandler(.performDefaultHandling, nil)
            return
        }
        var error: CFError?
        if SecTrustEvaluateWithError(serverTrust, &error) {
            completionHandler(.useCredential, URLCredential(trust: serverTrust))
        } else {
            completionHandler(.cancelAuthenticationChallenge, nil)
        }
    }
}

struct MastgTest {
    private static var insecureDelegate: InsecureURLSessionDelegate?
    private static var secureDelegate: SecureURLSessionDelegate?

    static func mastgTest(completion: @escaping (String) -> Void) {
        guard let url = URL(string: "https://expired.badssl.com/") else {
            DispatchQueue.main.async { completion("Invalid URL") }
            return
        }

        let insecureDel = InsecureURLSessionDelegate()
        MastgTest.insecureDelegate = insecureDel
        let insecureSession = URLSession(configuration: .default, delegate: insecureDel, delegateQueue: nil)

        insecureSession.dataTask(with: url) { _, response, error in
            let insecureResult: String
            if let http = response as? HTTPURLResponse {
                insecureResult = "INSECURE: expired.badssl.com accepted (HTTP \(http.statusCode)) — SecTrustEvaluateWithError not called"
            } else {
                insecureResult = "INSECURE: \(error?.localizedDescription ?? "unknown error")"
            }

            let secureDel = SecureURLSessionDelegate()
            MastgTest.secureDelegate = secureDel
            let secureSession = URLSession(configuration: .default, delegate: secureDel, delegateQueue: nil)

            secureSession.dataTask(with: url) { _, response, error in
                let secureResult: String
                if let http = response as? HTTPURLResponse {
                    secureResult = "SECURE (unexpected): expired.badssl.com accepted (HTTP \(http.statusCode))"
                } else {
                    secureResult = "SECURE: expired.badssl.com rejected — \(error?.localizedDescription ?? "certificate invalid")"
                }
                DispatchQueue.main.async {
                    completion("\(insecureResult)\n\n\(secureResult)")
                }
            }.resume()
        }.resume()
    }
}

Steps

  1. Extract the app ( Exploring the App Package) and locate the main binary ./Payload/MASTestApp.app/MASTestApp.
  2. Run radare2 (iOS) with the script to identify all URLSession authentication challenge handlers and determine which ones call SecTrustEvaluateWithError.
auth_challenge.r2
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
e scr.color=false
e asm.bytes=false
e asm.var=false

?e Custom authentication-challenge handlers (functions referencing NSURLAuthenticationChallenge):
is~NSURLAuthenticationChallenge

?e

?e Accessors into the challenge protection space (protectionSpace / serverTrust):
is~protectionSpace,serverTrust

?e

?e xrefs to URLSession challenge handler implementations:
axff @@ `f~URLSessionDelegate~didReceiveChallenge`~+didreceive

?e

?e Uses of SecTrustEvaluateWithError  shows which handlers properly evaluate server trust:
is~SecTrustEvaluateWithError

?e

?e xrefs to SecTrustEvaluateWithError:

axt @ sym.imp.SecTrustEvaluateWithError

pdf @ sym.MASTestApp.InsecureURLSessionDelegate.urlSession.allocator.didReceive.completionHandler_...o15NSURLCredentialCSgtctF_ > InsecureURLSessionDelegate.asm
pdf @ sym.MASTestApp.SecureURLSessionDelegate.urlSession.allocator.didReceive.completionHandler_...o15NSURLCredentialCSgtctF_ > SecureURLSessionDelegate.asm
run.sh
1
2
#!/bin/bash
r2 -q -i auth_challenge.r2 -A MASTestApp > output.txt

Observation

The output contains five sections followed by separate disassembly files for each handler:

  • Custom authentication-challenge handlers: lists every function whose signature references NSURLAuthenticationChallenge. Both InsecureURLSessionDelegate (0x00004000) and SecureURLSessionDelegate (0x00004490) appear here because both implement a custom challenge handler. This is the broad signal that the app has taken over part of the server trust evaluation, regardless of whether it does so correctly.
  • Accessors into the challenge protection space: the objc_msgSend$protectionSpace (0x000165e0) and objc_msgSend$serverTrust (0x00016620) stubs confirm the app reaches into challenge.protectionSpace.serverTrust, an indication of manual server trust handling.
  • xrefs to URLSession challenge handler implementations: axff on both ObjC challenge handler methods shows their calls to the underlying Swift implementations. InsecureURLSessionDelegate's ObjC method (0x41f8) calls the Swift implementation at 0x00004000. SecureURLSessionDelegate's ObjC method (0x4780) calls its Swift implementation at 0x00004490.
  • Uses of SecTrustEvaluateWithError: confirms SecTrustEvaluateWithError is imported into the binary (imp.SecTrustEvaluateWithError at 0x000161bc).
  • xrefs to SecTrustEvaluateWithError: only SecureURLSessionDelegate's Swift implementation (0x4490) calls SecTrustEvaluateWithError, at offset 0x4638. InsecureURLSessionDelegate's implementation (0x4000) has no entry here.

Reviewing the disassembled code ( Reviewing Disassembled Objective-C and Swift Code), the disassembly and AI-reversed Swift below show the insecure handler:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Custom authentication-challenge handlers (functions referencing NSURLAuthenticationChallenge):
50   0x00004490 0x00004490 GLOBAL FUNC 0        _$s10MASTestApp24SecureURLSessionDelegateC10urlSession_10didReceive17completionHandlerySo12NSURLSessionC_So28NSURLAuthenticationChallengeCySo0l4AuthN11DispositionV_So15NSURLCredentialCSgtctF                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           MASTestApp.SecureURLSessionDelegate.urlSession.allocator.didReceive.completionHandler(...o15NSURLCredentialCSgtctF)
51   0x00018968 0x00018968 GLOBAL FUNC 0        _$s10MASTestApp24SecureURLSessionDelegateC10urlSession_10didReceive17completionHandlerySo12NSURLSessionC_So28NSURLAuthenticationChallengeCySo0l4AuthN11DispositionV_So15NSURLCredentialCSgtctFTq                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         MASTestApp.SecureURLSessionDelegate.urlSession.allocator.didReceive.completionHandler(...o15NSURLCredentialCSgtctFTq)
58   0x00004000 0x00004000 GLOBAL FUNC 0        _$s10MASTestApp26InsecureURLSessionDelegateC10urlSession_10didReceive17completionHandlerySo12NSURLSessionC_So28NSURLAuthenticationChallengeCySo0l4AuthN11DispositionV_So15NSURLCredentialCSgtctF                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         MASTestApp.InsecureURLSessionDelegate.urlSession.allocator.didReceive.completionHandler(...o15NSURLCredentialCSgtctF)
59   0x0001892c 0x0001892c GLOBAL FUNC 0        _$s10MASTestApp26InsecureURLSessionDelegateC10urlSession_10didReceive17completionHandlerySo12NSURLSessionC_So28NSURLAuthenticationChallengeCySo0l4AuthN11DispositionV_So15NSURLCredentialCSgtctFTq                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       MASTestApp.InsecureURLSessionDelegate.urlSession.allocator.didReceive.completionHandler(...o15NSURLCredentialCSgtctFTq)
90   0x000041f8 0x000041f8 LOCAL  FUNC 0        _$s10MASTestApp26InsecureURLSessionDelegateC10urlSession_10didReceive17completionHandlerySo12NSURLSessionC_So28NSURLAuthenticationChallengeCySo0l4AuthN11DispositionV_So15NSURLCredentialCSgtctFTo                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       MASTestApp.InsecureURLSessionDelegate.urlSession.allocator.didReceive.completionHandler(...o15NSURLCredentialCSgtctFTo)
95   0x00004780 0x00004780 LOCAL  FUNC 0        _$s10MASTestApp24SecureURLSessionDelegateC10urlSession_10didReceive17completionHandlerySo12NSURLSessionC_So28NSURLAuthenticationChallengeCySo0l4AuthN11DispositionV_So15NSURLCredentialCSgtctFTo                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         MASTestApp.SecureURLSessionDelegate.urlSession.allocator.didReceive.completionHandler(...o15NSURLCredentialCSgtctFTo)

Accessors into the challenge protection space (protectionSpace / serverTrust):
455  0x000165e0 0x000165e0 LOCAL  FUNC 0        _objc_msgSend$protectionSpace
457  0x00016620 0x00016620 LOCAL  FUNC 0        _objc_msgSend$serverTrust

xrefs to URLSession challenge handler implementations:
ICOD 0x00004290 0x00004000 sym.MASTestApp.InsecureURLSessionDelegate.urlSession.allocator.didReceive.completionHandler_...o15NSURLCredentialCSgtctF_
CALL 0x00004298 0x00004000 sym.MASTestApp.InsecureURLSessionDelegate.urlSession.allocator.didReceive.completionHandler_...o15NSURLCredentialCSgtctF_
ICOD 0x00004818 0x00004000 sym.MASTestApp.InsecureURLSessionDelegate.urlSession.allocator.didReceive.completionHandler_...o15NSURLCredentialCSgtctF_
CALL 0x00004820 0x00004490 sym.MASTestApp.SecureURLSessionDelegate.urlSession.allocator.didReceive.completionHandler_...o15NSURLCredentialCSgtctF_

Uses of SecTrustEvaluateWithError — shows which handlers properly evaluate server trust:
949  0x000161bc 0x000161bc LOCAL  FUNC 0        imp.SecTrustEvaluateWithError

xrefs to SecTrustEvaluateWithError:
sym.MASTestApp.SecureURLSessionDelegate.urlSession.allocator.didReceive.completionHandler_...o15NSURLCredentialCSgtctF_ 0x4638 [CALL:--x] bl sym.imp.SecTrustEvaluateWithError
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
            ;-- section.0.__TEXT.__text:
            ;-- pc:
            ; CALL XREFS from func.000041f8 @ 0x4290(x), 0x4298(x) ; method.MASTestApp.InsecureURLSessionDelegate.URLSession:didReceiveChallenge:completionHandler:
            ; ICOD XREF from func.00004780 @ 0x4818(x) ; method.MASTestApp.SecureURLSessionDelegate.URLSession:didReceiveChallenge:completionHandler:
 348: NSURLCredential.allocator__GenericAccessorSgtctF_..partial.apply (int64_t arg1, int64_t arg2, int64_t arg3, void *arg4, int64_t arg_a0h);
           0x00004000      sub sp, sp, 0xa0                           ; [00] -r-x section size 72384 named 0.__TEXT.__text
           0x00004004      stp x20, x19, [var_80h]
           0x00004008      stp x29, x30, [var_90h]
           0x0000400c      add x29, sp, 0x90
           0x00004010      mov x8, x0                                 ; arg1
           0x00004014      mov x0, x1                                 ; arg2
           0x00004018      str x2, [var_28h]                          ; arg3
           0x0000401c      str x3, [arg0]                             ; arg4
           0x00004020      stur xzr, [x29, -0x18]
           0x00004024      stur xzr, [x29, -0x20]
           0x00004028      stur xzr, [x29, -0x30]
           0x0000402c      stur xzr, [x29, -0x28]
           0x00004030      stur xzr, [x29, -0x38]
           0x00004034      stur xzr, [x29, -0x40]
           0x00004038      stur x8, [x29, -0x18]
           0x0000403c      mov x8, x0
           0x00004040      stur x8, [x29, -0x20]
           0x00004044      stur x2, [x29, -0x30]                      ; arg3
           0x00004048      stur x3, [x29, -0x28]                      ; arg4
           0x0000404c      stur x20, [x29, -0x38]
           0x00004050      bl sym._objc_msgSend_protectionSpace
           0x00004054      mov x29, x29
           0x00004058      bl sym.imp.objc_retainAutoreleasedReturnValue ; void objc_retainAutoreleasedReturnValue(void *instance)
           0x0000405c      ldr x1, [var_38h]
           0x00004060      str x0, [var_40h]
           0x00004064      bl sym._objc_msgSend_serverTrust
           0x00004068      mov x29, x29
           0x0000406c      bl sym.imp.objc_retainAutoreleasedReturnValue ; void objc_retainAutoreleasedReturnValue(void *instance)
           0x00004070      mov x8, x0
           0x00004074      ldr x0, [var_40h]
           0x00004078      str x8, [var_48h]
           0x0000407c      adrp x8, segment.__DATA_CONST              ; 0x20000
           0x00004080      ldr x8, [x8, 0x118]                        ; [0x20118:8]=0x8010000000000021 ; "!"
           0x00004084      blr x8
           0x00004088      ldr x0, [var_48h]
       ┌─< 0x0000408c      cbz x0, 0x4120
      ┌──< 0x00004090      b 0x4094
      ││   ; CODE XREF from func.00004000 @ 0x4090(x)
      └──> 0x00004094      ldr x8, [var_48h]
          0x00004098      str x8, [var_20h]
      ┌──< 0x0000409c      b 0x40a0
      ││   ; CODE XREF from func.00004000 @ 0x409c(x)
      └──> 0x000040a0      ldr x0, [arg0]
          0x000040a4      ldr x8, [var_20h]
          0x000040a8      str x8, [var_18h]
          0x000040ac      stur x8, [x29, -0x40]
          0x000040b0      bl sym.imp.swift_retain
          0x000040b4      mov x0, 0                                  ; int64_t arg_20h
          0x000040b8      str x0, [var_8h]
          0x000040bc      bl sym....sSo15NSURLCredentialCMa          ; func.0000415c
          0x000040c0      mov x20, x0
          0x000040c4      ldr x0, [var_18h]
          0x000040c8      adrp x8, segment.__DATA_CONST              ; 0x20000
          0x000040cc      ldr x8, [x8, 0x120]                        ; [0x20120:8]=0x8010000000000022 ; "\""
          0x000040d0      blr x8
          0x000040d4      ldr x0, [var_18h]                          ; int64_t arg1
          0x000040d8      bl sym.__C.NSURLCredential                 ; func.000041bc
          0x000040dc      ldr x20, [arg0]
          0x000040e0      ldr x8, [var_28h]
          0x000040e4      mov x1, x0
          0x000040e8      ldr x0, [var_8h]
          0x000040ec      str x1, [var_10h]
          0x000040f0      blr x8
          0x000040f4      ldr x0, [var_10h]
          0x000040f8      adrp x8, segment.__DATA_CONST              ; 0x20000
          0x000040fc      ldr x8, [x8, 0x118]                        ; [0x20118:8]=0x8010000000000021 ; "!"
          0x00004100      blr x8
          0x00004104      ldr x0, [arg0]                             ; void *arg0
          0x00004108      bl sym.imp.swift_release                   ; void swift_release(void *arg0)
          0x0000410c      ldr x0, [var_18h]
          0x00004110      adrp x8, segment.__DATA_CONST              ; 0x20000
          0x00004114      ldr x8, [x8, 0x118]                        ; [0x20118:8]=0x8010000000000021 ; "!"
          0x00004118      blr x8
      ┌──< 0x0000411c      b 0x414c
      ││   ; CODE XREF from func.00004000 @ 0x408c(x)
      │└─> 0x00004120      ldr x20, [arg0]
          0x00004124      mov x0, x20
          0x00004128      bl sym.imp.swift_retain
          0x0000412c      ldr x8, [var_28h]
          0x00004130      mov w9, 2
          0x00004134      mov x0, x9
          0x00004138      mov x1, 0
          0x0000413c      blr x8
          0x00004140      ldr x0, [arg0]                             ; void *arg0
          0x00004144      bl sym.imp.swift_release                   ; void swift_release(void *arg0)
      │┌─< 0x00004148      b 0x414c
      ││   ; CODE XREFS from func.00004000 @ 0x411c(x), 0x4148(x)
      └└─> 0x0000414c      ldp x29, x30, [var_90h]
           0x00004150      ldp x20, x19, [var_80h]
           0x00004154      add sp, sp, 0xa0                           ; 0x178000
           0x00004158      ret
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import Foundation

class InsecureURLSessionDelegate: NSObject, URLSessionDelegate {
    func urlSession(
        _ session: URLSession,
        didReceive challenge: URLAuthenticationChallenge,
        completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void
    ) {
        if let serverTrust = challenge.protectionSpace.serverTrust {
            let credential = URLCredential(trust: serverTrust)
            completionHandler(.useCredential, credential)
        } else {
            completionHandler(.cancelAuthenticationChallenge, nil)
        }
    }
}

Evaluation

Both delegates surface in the "Custom authentication-challenge handlers" section, so both have taken control of the server trust evaluation and warrant manual review. The cross-reference to SecTrustEvaluateWithError is what distinguishes the secure handler (0x4490) from the insecure one (0x4000).

The test case fails because InsecureURLSessionDelegate's implementation (0x00004000) does not appear in the "xrefs to SecTrustEvaluateWithError" section.

The disassembly confirms this:

  • serverTrust is obtained at 0x00004064.
  • the only check is a nil guard at 0x0000408c (cbz x0, 0x4120).
  • NSURLCredential is created directly at 0x000040d8 with no call to SecTrustEvaluateWithError anywhere in the function.

The AI-reversed Swift makes the pattern explicit: any non-nil trust object is accepted unconditionally.

In contrast, SecureURLSessionDelegate's implementation (0x00004490) calls SecTrustEvaluateWithError at 0x00004638 and only creates a URLCredential if that call returns true (tbz w0, 0, 0x46a8 branches to the cancel path on failure):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Custom authentication-challenge handlers (functions referencing NSURLAuthenticationChallenge):
50   0x00004490 0x00004490 GLOBAL FUNC 0        _$s10MASTestApp24SecureURLSessionDelegateC10urlSession_10didReceive17completionHandlerySo12NSURLSessionC_So28NSURLAuthenticationChallengeCySo0l4AuthN11DispositionV_So15NSURLCredentialCSgtctF                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           MASTestApp.SecureURLSessionDelegate.urlSession.allocator.didReceive.completionHandler(...o15NSURLCredentialCSgtctF)
51   0x00018968 0x00018968 GLOBAL FUNC 0        _$s10MASTestApp24SecureURLSessionDelegateC10urlSession_10didReceive17completionHandlerySo12NSURLSessionC_So28NSURLAuthenticationChallengeCySo0l4AuthN11DispositionV_So15NSURLCredentialCSgtctFTq                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         MASTestApp.SecureURLSessionDelegate.urlSession.allocator.didReceive.completionHandler(...o15NSURLCredentialCSgtctFTq)
58   0x00004000 0x00004000 GLOBAL FUNC 0        _$s10MASTestApp26InsecureURLSessionDelegateC10urlSession_10didReceive17completionHandlerySo12NSURLSessionC_So28NSURLAuthenticationChallengeCySo0l4AuthN11DispositionV_So15NSURLCredentialCSgtctF                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         MASTestApp.InsecureURLSessionDelegate.urlSession.allocator.didReceive.completionHandler(...o15NSURLCredentialCSgtctF)
59   0x0001892c 0x0001892c GLOBAL FUNC 0        _$s10MASTestApp26InsecureURLSessionDelegateC10urlSession_10didReceive17completionHandlerySo12NSURLSessionC_So28NSURLAuthenticationChallengeCySo0l4AuthN11DispositionV_So15NSURLCredentialCSgtctFTq                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       MASTestApp.InsecureURLSessionDelegate.urlSession.allocator.didReceive.completionHandler(...o15NSURLCredentialCSgtctFTq)
90   0x000041f8 0x000041f8 LOCAL  FUNC 0        _$s10MASTestApp26InsecureURLSessionDelegateC10urlSession_10didReceive17completionHandlerySo12NSURLSessionC_So28NSURLAuthenticationChallengeCySo0l4AuthN11DispositionV_So15NSURLCredentialCSgtctFTo                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       MASTestApp.InsecureURLSessionDelegate.urlSession.allocator.didReceive.completionHandler(...o15NSURLCredentialCSgtctFTo)
95   0x00004780 0x00004780 LOCAL  FUNC 0        _$s10MASTestApp24SecureURLSessionDelegateC10urlSession_10didReceive17completionHandlerySo12NSURLSessionC_So28NSURLAuthenticationChallengeCySo0l4AuthN11DispositionV_So15NSURLCredentialCSgtctFTo                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         MASTestApp.SecureURLSessionDelegate.urlSession.allocator.didReceive.completionHandler(...o15NSURLCredentialCSgtctFTo)

Accessors into the challenge protection space (protectionSpace / serverTrust):
455  0x000165e0 0x000165e0 LOCAL  FUNC 0        _objc_msgSend$protectionSpace
457  0x00016620 0x00016620 LOCAL  FUNC 0        _objc_msgSend$serverTrust

xrefs to URLSession challenge handler implementations:
ICOD 0x00004290 0x00004000 sym.MASTestApp.InsecureURLSessionDelegate.urlSession.allocator.didReceive.completionHandler_...o15NSURLCredentialCSgtctF_
CALL 0x00004298 0x00004000 sym.MASTestApp.InsecureURLSessionDelegate.urlSession.allocator.didReceive.completionHandler_...o15NSURLCredentialCSgtctF_
ICOD 0x00004818 0x00004000 sym.MASTestApp.InsecureURLSessionDelegate.urlSession.allocator.didReceive.completionHandler_...o15NSURLCredentialCSgtctF_
CALL 0x00004820 0x00004490 sym.MASTestApp.SecureURLSessionDelegate.urlSession.allocator.didReceive.completionHandler_...o15NSURLCredentialCSgtctF_

Uses of SecTrustEvaluateWithError — shows which handlers properly evaluate server trust:
949  0x000161bc 0x000161bc LOCAL  FUNC 0        imp.SecTrustEvaluateWithError

xrefs to SecTrustEvaluateWithError:
sym.MASTestApp.SecureURLSessionDelegate.urlSession.allocator.didReceive.completionHandler_...o15NSURLCredentialCSgtctF_ 0x4638 [CALL:--x] bl sym.imp.SecTrustEvaluateWithError
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
            ; CALL XREF from func.00004780 @ 0x4820(x) ; method.MASTestApp.SecureURLSessionDelegate.URLSession:didReceiveChallenge:completionHandler:
 704: NSURLCredential.allocator__GenericAccessorSgtctF_..partial.apply (int64_t arg1, int64_t arg2, int64_t arg3, void *arg4, int64_t arg_f0h);
; MASTestApp.SecureURLSessionDelegate.urlSession.allocator.didReceive.
; completionHandler(...o15NSURLCredentialCSgtctF)
           0x00004490      sub sp, sp, 0xf0
           0x00004494      stp x20, x19, [var_d0h]
           0x00004498      stp x29, x30, [var_e0h]
           0x0000449c      add x29, sp, 0xe0
           0x000044a0      mov x8, x0                                 ; arg1
           0x000044a4      mov x0, x1                                 ; arg2
           0x000044a8      str x0, [var_30h]
           0x000044ac      str x2, [var_38h]                          ; arg3
           0x000044b0      str x3, [var_40h]                          ; arg4
           0x000044b4      adrp x9, segment.__DATA_CONST              ; 0x20000
           0x000044b8      ldr x9, [x9, 0x158]                        ; [0x20158:8]=0x8010000000000029 ; ")"
           0x000044bc      ldr x9, [x9]
           0x000044c0      stur x9, [x29, -0x18]
           0x000044c4      stur xzr, [x29, -0x28]
           0x000044c8      stur xzr, [x29, -0x30]
           0x000044cc      stur xzr, [x29, -0x40]
           0x000044d0      stur xzr, [x29, -0x38]
           0x000044d4      stur xzr, [x29, -0x48]
           0x000044d8      stur xzr, [x29, -0x50]
           0x000044dc      stur x8, [x29, -0x28]
           0x000044e0      mov x8, x0
           0x000044e4      stur x8, [x29, -0x30]
           0x000044e8      stur x2, [x29, -0x40]                      ; arg3
           0x000044ec      stur x3, [x29, -0x38]                      ; arg4
           0x000044f0      stur x20, [x29, -0x48]
           0x000044f4      bl sym._objc_msgSend_protectionSpace
           0x000044f8      mov x29, x29
           0x000044fc      bl sym.imp.objc_retainAutoreleasedReturnValue ; void objc_retainAutoreleasedReturnValue(void *instance)
           0x00004500      ldr x1, [var_48h]
           0x00004504      str x0, [var_50h]
           0x00004508      bl sym._objc_msgSend_authenticationMethod
           0x0000450c      mov x29, x29
           0x00004510      bl sym.imp.objc_retainAutoreleasedReturnValue ; void objc_retainAutoreleasedReturnValue(void *instance)
           0x00004514      mov x8, x0
           0x00004518      ldr x0, [var_50h]
           0x0000451c      str x8, [var_58h]
           0x00004520      adrp x8, segment.__DATA_CONST              ; 0x20000
           0x00004524      ldr x8, [x8, 0x118]                        ; [0x20118:8]=0x8010000000000021 ; "!"
           0x00004528      blr x8
           0x0000452c      ldr x0, [var_58h]
           0x00004530      bl sym.imp.Foundation_...nconditionallyBridgeFromObjectiveCySSSo8NSStringCSgFZ_ ; Foundation(...nconditionallyBridgeFromObjectiveCySSSo8NSStringCSgFZ)
           0x00004534      mov x2, x0
           0x00004538      ldr x0, [var_58h]
           0x0000453c      str x2, [var_68h]
           0x00004540      stur x1, [x29, -0x60]
           0x00004544      adrp x8, segment.__DATA_CONST              ; 0x20000
           0x00004548      ldr x8, [x8, 0x118]                        ; [0x20118:8]=0x8010000000000021 ; "!"
           0x0000454c      blr x8
           0x00004550      adrp x8, segment.__DATA_CONST              ; 0x20000
           0x00004554      ldr x8, [x8, 0xf0]                         ; [0x200f0:8]=0x801000000000001c ; reloc.NSURLAuthenticationMethodServerTrust
           0x00004558      ldr x0, [x8]
           0x0000455c      str x0, [var_60h]
           0x00004560      adrp x8, segment.__DATA_CONST              ; 0x20000
           0x00004564      ldr x8, [x8, 0x120]                        ; [0x20120:8]=0x8010000000000022 ; "\""
           0x00004568      blr x8
           0x0000456c      ldr x0, [var_60h]
           0x00004570      bl sym.imp.Foundation_...nconditionallyBridgeFromObjectiveCySSSo8NSStringCSgFZ_ ; Foundation(...nconditionallyBridgeFromObjectiveCySSSo8NSStringCSgFZ)
           0x00004574      mov x2, x0
           0x00004578      ldr x0, [var_60h]
           0x0000457c      str x2, [var_70h]
           0x00004580      stur x1, [x29, -0x68]
           0x00004584      adrp x8, segment.__DATA_CONST              ; 0x20000
           0x00004588      ldr x8, [x8, 0x118]                        ; [0x20118:8]=0x8010000000000021 ; "!"
           0x0000458c      blr x8
           0x00004590      ldr x0, [var_68h]
           0x00004594      ldr x2, [var_70h]
           0x00004598      ldur x3, [x29, -0x68]
           0x0000459c      ldur x1, [x29, -0x60]
           0x000045a0      bl sym.imp.Swift__String_...tFZ_           ; Swift__String(...tFZ)
           0x000045a4      mov x8, x0
           0x000045a8      ldur x0, [x29, -0x68]                      ; void *arg0
           0x000045ac      stur w8, [x29, -0x54]
           0x000045b0      bl sym.imp.swift_bridgeObjectRelease       ; void swift_bridgeObjectRelease(void *arg0)
           0x000045b4      ldur x0, [x29, -0x60]                      ; void *arg0
           0x000045b8      bl sym.imp.swift_bridgeObjectRelease       ; void swift_bridgeObjectRelease(void *arg0)
           0x000045bc      ldur w0, [x29, -0x54]
       ┌─< 0x000045c0      tbz w0, 0, 0x46f0
      ┌──< 0x000045c4      b 0x45c8
      ││   ; CODE XREF from func.00004490 @ 0x45c4(x)
      └──> 0x000045c8      ldr x1, [var_48h]
          0x000045cc      ldr x0, [var_30h]
          0x000045d0      bl sym._objc_msgSend_protectionSpace
          0x000045d4      mov x29, x29
          0x000045d8      bl sym.imp.objc_retainAutoreleasedReturnValue ; void objc_retainAutoreleasedReturnValue(void *instance)
          0x000045dc      ldr x1, [var_48h]
          0x000045e0      str x0, [var_20h]
          0x000045e4      bl sym._objc_msgSend_serverTrust
          0x000045e8      mov x29, x29
          0x000045ec      bl sym.imp.objc_retainAutoreleasedReturnValue ; void objc_retainAutoreleasedReturnValue(void *instance)
          0x000045f0      mov x8, x0
          0x000045f4      ldr x0, [var_20h]
          0x000045f8      str x8, [var_28h]
          0x000045fc      adrp x8, segment.__DATA_CONST              ; 0x20000
          0x00004600      ldr x8, [x8, 0x118]                        ; [0x20118:8]=0x8010000000000021 ; "!"
          0x00004604      blr x8
          0x00004608      ldr x0, [var_28h]
      ┌──< 0x0000460c      cbz x0, 0x4620
     ┌───< 0x00004610      b 0x4614
     │││   ; CODE XREF from func.00004490 @ 0x4610(x)
     └───> 0x00004614      ldr x8, [var_28h]
      ││   0x00004618      str x8, [var_18h]
     ┌───< 0x0000461c      b 0x4624
     │││   ; CODE XREF from func.00004490 @ 0x460c(x)
    ┌─└──> 0x00004620      b 0x46f4
    ││    ; CODE XREF from func.00004490 @ 0x461c(x)
    │└───> 0x00004624      ldr x0, [var_18h]
         0x00004628      str x0, [var_10h]
         0x0000462c      stur x0, [x29, -0x50]
         0x00004630      sub x1, x29, 0x20
         0x00004634      stur xzr, [x29, -0x20]
         0x00004638      bl sym.imp.SecTrustEvaluateWithError
     ┌──< 0x0000463c      tbz w0, 0, 0x46a8
    │┌───< 0x00004640      b 0x4644
    ││││   ; CODE XREF from func.00004490 @ 0x4640(x)
    │└───> 0x00004644      ldr x0, [var_40h]
     ││   0x00004648      bl sym.imp.swift_retain
     ││   0x0000464c      mov x0, 0                                  ; int64_t arg_20h
     ││   0x00004650      str x0, [sp]
     ││   0x00004654      bl sym....sSo15NSURLCredentialCMa          ; func.0000415c
     ││   0x00004658      mov x20, x0
     ││   0x0000465c      ldr x0, [var_10h]
     ││   0x00004660      adrp x8, segment.__DATA_CONST              ; 0x20000
     ││   0x00004664      ldr x8, [x8, 0x120]                        ; [0x20120:8]=0x8010000000000022 ; "\""
     ││   0x00004668      blr x8
     ││   0x0000466c      ldr x0, [var_10h]                          ; int64_t arg1
     ││   0x00004670      bl sym.__C.NSURLCredential                 ; func.000041bc
     ││   0x00004674      ldr x20, [var_40h]
     ││   0x00004678      ldr x8, [var_38h]
     ││   0x0000467c      mov x1, x0
     ││   0x00004680      ldr x0, [sp]
     ││   0x00004684      str x1, [var_8h]
     ││   0x00004688      blr x8
     ││   0x0000468c      ldr x0, [var_8h]
     ││   0x00004690      adrp x8, segment.__DATA_CONST              ; 0x20000
     ││   0x00004694      ldr x8, [x8, 0x118]                        ; [0x20118:8]=0x8010000000000021 ; "!"
     ││   0x00004698      blr x8
     ││   0x0000469c      ldr x0, [var_40h]                          ; void *arg0
     ││   0x000046a0      bl sym.imp.swift_release                   ; void swift_release(void *arg0)
    │┌───< 0x000046a4      b 0x46d4
    ││││   ; CODE XREF from func.00004490 @ 0x463c(x)
    ││└──> 0x000046a8      ldr x20, [var_40h]
    ││    0x000046ac      mov x0, x20
    ││    0x000046b0      bl sym.imp.swift_retain
    ││    0x000046b4      ldr x8, [var_38h]
    ││    0x000046b8      mov w9, 2
    ││    0x000046bc      mov x0, x9
    ││    0x000046c0      mov x1, 0
    ││    0x000046c4      blr x8
    ││    0x000046c8      ldr x0, [var_40h]                          ; void *arg0
    ││    0x000046cc      bl sym.imp.swift_release                   ; void swift_release(void *arg0)
    ││┌──< 0x000046d0      b 0x46d4
    ││││   ; CODE XREFS from func.00004490 @ 0x46a4(x), 0x46d0(x)
    │└└──> 0x000046d4      sub x0, x29, 0x20                          ; int64_t arg1
         0x000046d8      bl sym....sSo10CFErrorRefaSgWOh            ; func.00004750
         0x000046dc      ldr x0, [var_10h]
         0x000046e0      adrp x8, segment.__DATA_CONST              ; 0x20000
         0x000046e4      ldr x8, [x8, 0x118]                        ; [0x20118:8]=0x8010000000000021 ; "!"
         0x000046e8      blr x8
     ┌──< 0x000046ec      b 0x4720
     ││   ; CODE XREF from func.00004490 @ 0x45c0(x)
    │┌─└─> 0x000046f0      b 0x46f4
    │││    ; CODE XREFS from func.00004490 @ 0x4620(x), 0x46f0(x)
    └└───> 0x000046f4      ldr x20, [var_40h]
          0x000046f8      mov x0, x20
          0x000046fc      bl sym.imp.swift_retain
          0x00004700      ldr x8, [var_38h]
          0x00004704      mov w9, 1
          0x00004708      mov x0, x9
          0x0000470c      mov x1, 0
          0x00004710      blr x8
          0x00004714      ldr x0, [var_40h]                          ; void *arg0
          0x00004718      bl sym.imp.swift_release                   ; void swift_release(void *arg0)
      │┌─< 0x0000471c      b 0x4720
      ││   ; CODE XREFS from func.00004490 @ 0x46ec(x), 0x471c(x)
      └└─> 0x00004720      ldur x9, [x29, -0x18]
           0x00004724      adrp x8, segment.__DATA_CONST              ; 0x20000
           0x00004728      ldr x8, [x8, 0x158]                        ; [0x20158:8]=0x8010000000000029 ; ")"
           0x0000472c      ldr x8, [x8]
           0x00004730      subs x8, x8, x9
       ┌─< 0x00004734      b.eq 0x4740
      ┌──< 0x00004738      b 0x473c
      ││   ; CODE XREF from func.00004490 @ 0x4738(x)
      └──> 0x0000473c      bl sym.imp.__stack_chk_fail                ; void stack_chk_fail(void)
          ; CODE XREF from func.00004490 @ 0x4734(x)
       └─> 0x00004740      ldp x29, x30, [var_e0h]
           0x00004744      ldp x20, x19, [var_d0h]
           0x00004748      add sp, sp, 0xf0                           ; 0x178000
           0x0000474c      ret
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import Foundation
import Security

class SecureURLSessionDelegate: NSObject, URLSessionDelegate {
    func urlSession(
        _ session: URLSession,
        didReceive challenge: URLAuthenticationChallenge,
        completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void
    ) {
        if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
            guard let serverTrust = challenge.protectionSpace.serverTrust else {
                completionHandler(.performDefaultHandling, nil)
                return
            }

            var error: CFError?
            if SecTrustEvaluateWithError(serverTrust, &error) {
                let credential = URLCredential(trust: serverTrust)
                completionHandler(.useCredential, credential)
            } else {
                completionHandler(.cancelAuthenticationChallenge, nil)
            }
        } else {
            completionHandler(.performDefaultHandling, nil)
        }
    }
}