iOS9 GoogleAnalytics and NSAppTransportSecurity

2019-02-01 21:14发布

问题:

I am running into trouble due to the new security opportunity from Apple's iOS9 to restrict ssl requests to any kind of servers.

See reference: https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW33

Actually, I want to make use of the default and not allow any kind of connection NSAllowsArbitraryLoads: false

<key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <false/>
    </dict>

Of course some connections are intended and I retrieve data from own servers as well as from third party servers.

Either you can now sniff the app's traffic, which is generated by third party tools, or you make use of logging all network traffic, referenced here: How can I figure out which URL is being blocked by App Transport Security?

It is easy to track down all occurring errors in this log (not too hard to look for an error code). In this way I was easily able to see what connections were being established and maybe failed, due to load limitations (of course, good software engineers know by heart ;) )

Any kind of third party tracker or the own network setup is running just fine, despite from Google Analytics. At first I downloaded the last Example codes and had a look at them, of course you cannot expect a library to already support most recent beta systems, nevertheless, I gave it a try. And it failed as soon as the NSAllowsArbitraryLoads is set to false/NO

Even with limiting as few as possible for the third party I was not able to make it run:

<key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <false/>
            <key>NSExceptionDomains</key>
            <dict>
        <key>ssl.google-analytics.com</key>
        <dict>
            <key>NSRequiresCertificateTransparency</key>
            <true/>
            <key>NSThirdPartyExceptionMinimumTLSVersion</key>
            <string>TLSv1.2</string>
            <key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
            <false/>
            <key>NSThirdPartyExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>

Also tried google-analytics.com and to include subdomains NSIncludesSubdomains:true. And, as the simple website call in browser of "https://google-analytics.com" redirects to "https://www.google.com/analytics/" I also tried to allow google.com as additional exception domain, which also fails.

Even had a look at the supported ssl-ciphers, I think they are no problem here:

nmap --script ssl-enum-ciphers -p 443 ssl.google-analytics.com

|   TLSv1.2: 
|     ciphers: 
|       TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA (dh 256) - C
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (dh 256) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (dh 256) - A
|       TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (dh 256) - A
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (dh 256) - A
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (dh 256) - A
|       TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (dh 256) - A
|       TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (dh 256) - A
|       TLS_ECDHE_RSA_WITH_RC4_128_SHA (dh 256) - A
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_GCM_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_GCM_SHA384 (rsa 2048) - A
|       TLS_RSA_WITH_RC4_128_MD5 (rsa 2048) - A
|       TLS_RSA_WITH_RC4_128_SHA (rsa 2048) - A

So, the google analytics tracking still fails for requests like: https://ssl.google-analytics.com/collect?[....]

Has anyone come up with a solution or maybe found some kind of mistake in my approach?

回答1:

Actually the above configuration was slightly wrong, I found a working approach.

-- Short story start --

Basically, the above approach was mostly correct, but I came up to check the configuration again, when I had a look at the established network connection from Mac OS 10.10 and OS 10.11

openssl s_client -connect ssl.google-analytics.com:443 -status

Mac OS 10.10 made use of TLSv1.2, while Mac OS 10.11 for whatever reason used TLSv1.0

-- Short story end --

So, after rethinking the attributes, I removed the Certificate transparency NSRequiresCertificateTransparency, as the default is also set to be false and not true. The following configuration now works for me:

<key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <false/>
        <key>NSExceptionDomains</key>
        <dict>
            <key>ssl.google-analytics.com</key>
            <dict>
                <key>NSThirdPartyExceptionMinimumTLSVersion</key>
                <string>TLSv1.2</string>
                <key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
                <false/>
                <key>NSThirdPartyExceptionAllowsInsecureHTTPLoads</key>
                <true/>
            </dict>
        </dict>
    </dict>

Additional note: although google makes use of this "experimental standard" (certificate transparency):https://en.wikipedia.org/wiki/Certificate_Transparency It seems to not make use of it in google analytics :-)