Which plan supports ATS-compliant SSL configuration?

I’m building a webhook handler for App store notifications. The current implementation does not accept connections from Apple because it doesn’t meet the requirements for App Transport Security (ATS). The diagnostic test of nscurl fails on three occasions:

TLSv1.3 with PFS disabled
TLSv1.3 with PFS disabled and insecure HTTP allowed
TLSv1.3

Is it possible to reconfigure this with the free plan? If not, which plan would support a custom SSL configuration that complies with ATS?

This new to me, but I ran Apple’s test on my free plan test site (with TLS 1.3 enabled along with RTT-0) and it looks like it passed.

[email protected] ~ % /usr/bin/nscurl --ats-diagnostics --verbose https://TEST.me
Starting ATS Diagnostics

Configuring ATS Info.plist keys and displaying the result of HTTPS loads to https://TEST.me.
A test will "PASS" if URLSession:task:didCompleteWithError: returns a nil error.
================================================================================

Default ATS Secure Connection
---
ATS Default Connection
ATS Dictionary:
{
}
Result : PASS
---

================================================================================

Allowing Arbitrary Loads

---
Allow All Loads
ATS Dictionary:
{
    NSAllowsArbitraryLoads = true;
}
Result : PASS
---

================================================================================

Configuring TLS exceptions for TEST.me

---
TLSv1.3
ATS Dictionary:
{
    NSExceptionDomains =     {
        "TEST.me" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.3";
        };
    };
}
Result : PASS
---

---
TLSv1.2
ATS Dictionary:
{
    NSExceptionDomains =     {
        "TEST.me" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.2";
        };
    };
}
Result : PASS
---

---
TLSv1.1
ATS Dictionary:
{
    NSExceptionDomains =     {
        "TEST.me" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.1";
        };
    };
}
Result : PASS
---

---
TLSv1.0
ATS Dictionary:
{
    NSExceptionDomains =     {
        "TEST.me" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.0";
        };
    };
}
Result : PASS
---

================================================================================

Configuring PFS exceptions for TEST.me

---
Disabling Perfect Forward Secrecy
ATS Dictionary:
{
    NSExceptionDomains =     {
        "TEST.me" =         {
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

================================================================================

Configuring PFS exceptions and allowing insecure HTTP for TEST.me

---
Disabling Perfect Forward Secrecy and Allowing Insecure HTTP
ATS Dictionary:
{
    NSExceptionDomains =     {
        "TEST.me" =         {
            NSExceptionAllowsInsecureHTTPLoads = true;
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

================================================================================

Configuring TLS exceptions with PFS disabled for TEST.me

---
TLSv1.3 with PFS disabled
ATS Dictionary:
{
    NSExceptionDomains =     {
        "TEST.me" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.3";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

---
TLSv1.2 with PFS disabled
ATS Dictionary:
{
    NSExceptionDomains =     {
        "TEST.me" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.2";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

---
TLSv1.1 with PFS disabled
ATS Dictionary:
{
    NSExceptionDomains =     {
        "TEST.me" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.1";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

---
TLSv1.0 with PFS disabled
ATS Dictionary:
{
    NSExceptionDomains =     {
        "TEST.me" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.0";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

================================================================================

Configuring TLS exceptions with PFS disabled and insecure HTTP allowed for TEST.me

---
TLSv1.3 with PFS disabled and insecure HTTP allowed
ATS Dictionary:
{
    NSExceptionDomains =     {
        "TEST.me" =         {
            NSExceptionAllowsInsecureHTTPLoads = true;
            NSExceptionMinimumTLSVersion = "TLSv1.3";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

---
TLSv1.2 with PFS disabled and insecure HTTP allowed
ATS Dictionary:
{
    NSExceptionDomains =     {
        "TEST.me" =         {
            NSExceptionAllowsInsecureHTTPLoads = true;
            NSExceptionMinimumTLSVersion = "TLSv1.2";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

---
TLSv1.1 with PFS disabled and insecure HTTP allowed
ATS Dictionary:
{
    NSExceptionDomains =     {
        "TEST.me" =         {
            NSExceptionAllowsInsecureHTTPLoads = true;
            NSExceptionMinimumTLSVersion = "TLSv1.1";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

---
TLSv1.0 with PFS disabled and insecure HTTP allowed
ATS Dictionary:
{
    NSExceptionDomains =     {
        "TEST.me" =         {
            NSExceptionAllowsInsecureHTTPLoads = true;
            NSExceptionMinimumTLSVersion = "TLSv1.0";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

================================================================================

Alright that’s good news & thanks! Now I know I have a re-configuration task ahead.

1 Like

Now I can’t find that 0-RTT setting. Maybe it’s on by default now.

Looking more closely, it seems that you’ve created exceptions to circumvent the protection provided by PFS, but I’m ok with that approach. I can disable PFS with TLSv1.3. I’ll still have to find out if it works.

1 Like

Really? I didn’t do anything. As I said, this is new to me as of right now. Exceptions where?

I believe those exceptions are defined in the “information property list” of your app. I’m not sure where that’s stored - locally or on some Apple server. I’m also not sure how the diagnostic test knows about them just by probing the server. But the ATS Dictionary looks familiar, and they keys and values set in it, right above the test result. Here’s what it looks like without any exceptions:

TLSv1.3 with PFS disabled
2020-10-06 11:27:22.502 nscurl[8495:70223] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9800)
Result : FAIL
TLSv1.3 with PFS disabled and insecure HTTP allowed
2020-10-06 11:27:23.435 nscurl[8495:70255] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9800)
Result : FAIL
11:29
TLSv1.3
2020-10-06 11:27:20.928 nscurl[8495:70255] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9800)
Result : FAIL

I just ran nscurl from the command line of my Mac following these instructions:

Me too! And my app seems to need some work because of the failed tests. I actually thought I could configure stuff on cloudflare, like define preferences for the cipher suites for different versions of TLS, but I’m not sure if that’s included in the free plan (or any other plan).

You probably could on Enterprise plan, but that’s pretty excessive.