swiftios9alamofireapp-transport-securitymoya

Bypassing App Transport Security to allow unsecured HTTP server


Situation:

I have to connect to these two different servers for development and staging use. Both of the servers have unstrusted SSL certificates. For example purposes, these two servers URL's are:

Staging server: https://52.70.13.2:1010/

Development server: https://example.entrydns.org:1012

Whenever I tried to call the API, i get empty response with following error:

NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)

or sometimes,

NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)

I use Moya for my network layers, which is basically just a nice wrapper for Alamofire. For additional info, I use XCode 7.3 and the app only supports > iOS 9.

What I've did:

I am very well aware of App Transport Security issue that Apple want to enforce. I wanted to disable it for development but still in vain. Some of the ways I tried to bypass the ATS it are as the following:

  1. Add the following in my plist to allow arbitrary loads.

    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>
    
  2. Explicitly defines the domain exceptions.

    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSExceptionDomains</key>
        <dict>
            <key>example.entrydns.org</key>
            <dict>
                <key>NSIncludesSubdomains</key>
                <true/>
                <key>NSExceptionAllowsInsecureHTTPLoads</key>
                <true/>
                <key>NSExceptionRequiresForwardSecrecy</key>
                <true/>
                <key>NSExceptionMinimumTLSVersion</key>
                <string>TLSv1.1</string>
                <key>NSThirdPartyExceptionAllowsInsecureHTTPLoads</key>
                <false/>
                <key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
                <true/>
                <key>NSThirdPartyExceptionMinimumTLSVersion</key>
                <string>TLSv1.1</string>
                <key>NSRequiresCertificateTransparency</key>
                <false/>
            </dict>
        </dict>
    </dict>
    

Here's the screenshot for my plist: enter image description here

  1. I also tried to disable the Server Trust Policy of Alamofire manager shared instance. Here's the example code:

    // Disable Policies
    let policies: [String: ServerTrustPolicy] = [
        "https://example.entrydns.org:1012/": .DisableEvaluation,
        "https://52.70.13.2:1010/": .DisableEvaluation
    ]
    
    let manager = Manager(
        configuration: NSURLSessionConfiguration.defaultSessionConfiguration(),
        serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies)
    )
     // ---------------
    let networkLogger = NetworkLoggerPlugin(verbose: true, responseDataFormatter: nil)
    
    let endpointClosure = { (target: ExampleAPI) -> Endpoint<ExampleAPI> in      
        let url = target.baseURL.URLByAppendingPathComponent(target.path).absoluteString
        let endpoint: Endpoint<ExampleAPI> = Endpoint<ExampleAPI>
                (URL: url,
                 sampleResponseClosure: {.NetworkResponse(200, target.sampleData)},
                 method: target.method,
                 parameters: target.parameters,
                 parameterEncoding: .URLEncodedInURL)
        return endpoint.endpointByAddingHTTPHeaderFields(target.header())
    }
    
    let ExampleProvider = MoyaProvider<ExampleAPI>(manager: manager,
                                           plugins:[networkLogger],
                                           endpointClosure: endpointClosure)
    
  2. Open the URLs and download the certs on my device and simulators.

Even after all the steps above I still got the same error. Any takes on what I did wrong and what I can do to solve this problem? BTW, it would be great if I can avoid server-side solution.

Thanks in advance.

References:


Solution

  • Define your policies with just the hostname.

    // Disable Policies
    let policies: [String: ServerTrustPolicy] = [
        "example.entrydns.org": .DisableEvaluation
    ]