Skip to content

MASTG-DEMO-0083: Insecure ATS Configuration Allowing Cleartext Traffic

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

Sample

The code below shows an insecure ATS configuration in an Info.plist file that disables App Transport Security in many ways:

  • Globally via NSAllowsArbitraryLoads
  • For web content via NSAllowsArbitraryLoadsInWebContent
  • For media via NSAllowsArbitraryLoadsForMedia
  • For local networking via NSAllowsArbitraryLoadsForLocalNetworking
  • For specific domains (api.example.com and httpbin.org) via NSExceptionDomains
 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
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>NSAppTransportSecurity</key>
        <dict>
            <key>NSAllowsArbitraryLoads</key>
            <true />

            <key>NSAllowsArbitraryLoadsInWebContent</key>
            <true />
            <key>NSAllowsArbitraryLoadsForMedia</key>
            <true />
            <key>NSAllowsArbitraryLoadsForLocalNetworking</key>
            <true />

            <key>NSExceptionDomains</key>
            <dict>

                <key>api.example.com</key>
                <dict>
                    <key>NSExceptionAllowsInsecureHTTPLoads</key>
                    <true />
                    <key>NSExceptionRequiresForwardSecrecy</key>
                    <false />
                    <key>NSTemporaryExceptionMinimumTLSVersion</key>
                    <string>TLSv1.0</string>
                    <key>NSIncludesSubdomains</key>
                    <true />
                </dict>

                <key>httpbin.org</key>
                <dict>
                    <key>NSExceptionAllowsInsecureHTTPLoads</key>
                    <true />
                    <key>NSExceptionMinimumTLSVersion</key>
                    <string>TLSv1.1</string>
                    <key>NSIncludesSubdomains</key>
                    <true />
                </dict>

            </dict>
        </dict>
    </dict>
</plist>
  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
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>BuildMachineOSBuild</key>
    <string>25C56</string>
    <key>CFBundleDevelopmentRegion</key>
    <string>en</string>
    <key>CFBundleExecutable</key>
    <string>MASTestApp</string>
    <key>CFBundleIdentifier</key>
    <string>org.owasp.mastestapp.MASTestApp-iOS</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>MASTestApp</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>1.0</string>
    <key>CFBundleSupportedPlatforms</key>
    <array>
        <string>iPhoneOS</string>
    </array>
    <key>CFBundleVersion</key>
    <string>1</string>
    <key>DTCompiler</key>
    <string>com.apple.compilers.llvm.clang.1_0</string>
    <key>DTPlatformBuild</key>
    <string>23C53</string>
    <key>DTPlatformName</key>
    <string>iphoneos</string>
    <key>DTPlatformVersion</key>
    <string>26.2</string>
    <key>DTSDKBuild</key>
    <string>23C53</string>
    <key>DTSDKName</key>
    <string>iphoneos26.2</string>
    <key>DTXcode</key>
    <string>2620</string>
    <key>DTXcodeBuild</key>
    <string>17C52</string>
    <key>LSRequiresIPhoneOS</key>
    <true/>
    <key>MinimumOSVersion</key>
    <string>17.1.1</string>
    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
        <key>NSAllowsArbitraryLoadsForLocalNetworking</key>
        <true/>
        <key>NSAllowsArbitraryLoadsForMedia</key>
        <true/>
        <key>NSAllowsArbitraryLoadsInWebContent</key>
        <true/>
        <key>NSExceptionDomains</key>
        <dict>
            <key>api.example.com</key>
            <dict>
                <key>NSExceptionAllowsInsecureHTTPLoads</key>
                <true/>
                <key>NSExceptionRequiresForwardSecrecy</key>
                <false/>
                <key>NSIncludesSubdomains</key>
                <true/>
                <key>NSTemporaryExceptionMinimumTLSVersion</key>
                <string>TLSv1.0</string>
            </dict>
            <key>httpbin.org</key>
            <dict>
                <key>NSExceptionAllowsInsecureHTTPLoads</key>
                <true/>
                <key>NSExceptionMinimumTLSVersion</key>
                <string>TLSv1.1</string>
                <key>NSIncludesSubdomains</key>
                <true/>
            </dict>
        </dict>
    </dict>
    <key>UIApplicationSceneManifest</key>
    <dict>
        <key>UIApplicationSupportsMultipleScenes</key>
        <true/>
        <key>UISceneConfigurations</key>
        <dict/>
    </dict>
    <key>UIApplicationSupportsIndirectInputEvents</key>
    <true/>
    <key>UIDeviceFamily</key>
    <array>
        <integer>1</integer>
        <integer>2</integer>
    </array>
    <key>UILaunchScreen</key>
    <dict>
        <key>UILaunchScreen</key>
        <dict/>
    </dict>
    <key>UIRequiredDeviceCapabilities</key>
    <array>
        <string>arm64</string>
    </array>
    <key>UISupportedInterfaceOrientations~ipad</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
        <string>UIInterfaceOrientationPortraitUpsideDown</string>
        <string>UIInterfaceOrientationLandscapeLeft</string>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
    <key>UISupportedInterfaceOrientations~iphone</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
        <string>UIInterfaceOrientationLandscapeLeft</string>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
</dict>
</plist>
 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
import Foundation

struct MastgTest {
    // SUMMARY: This sample demonstrates the use of hardcoded HTTP URLs in iOS apps.

    static let httpEndpoint = "http://httpbin.org/get"  // FAIL: [MASTG-TEST-0321] Hardcoded HTTP URL
    static let httpApiUrl = "http://example.com/api"    // FAIL: [MASTG-TEST-0321] Hardcoded HTTP URL
    static let httpsEndpoint = "https://httpbin.org/get" // PASS: [MASTG-TEST-0321] HTTPS URL

    static func mastgTest(completion: @escaping (String) -> Void) {
        var result = "Testing HTTP URL connections:\n\n"

        // Attempt to connect to HTTP endpoint
        if let url = URL(string: httpEndpoint) {
            let task = URLSession.shared.dataTask(with: url) { data, response, error in
                if let error = error {
                    result += "HTTP request to \(httpEndpoint) failed: \(error.localizedDescription)\n"
                } else if let httpResponse = response as? HTTPURLResponse {
                    result += "HTTP request to \(httpEndpoint) returned status: \(httpResponse.statusCode)\n"
                }
                completion(result)
            }
            task.resume()
        } else {
            result += "Invalid URL: \(httpEndpoint)\n"
            completion(result)
        }
    }
}

Steps

  1. Extract the app ( Exploring the App Package) and locate the Info.plist file inside the app bundle (which we'll name Info_reversed.plist).
  2. Convert the Info.plist to pretty printed JSON ( Convert Plist Files to JSON)
  3. Extract the relevant keys and values from the NSAppTransportSecurity configuration. In this case we use gron to transform the JSON into a greppable format and egrep to search for specific regex patterns.
run.sh
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#!/bin/bash

plutil -convert json -o Info_reversed.json Info_reversed.plist

# pretty print json
jq . Info_reversed.json > Info_reversed.json.tmp && mv Info_reversed.json.tmp Info_reversed.json

gron -m Info_reversed.json \
| egrep 'json\.NSAppTransportSecurity\.(NSAllowsArbitraryLoads|NSAllowsArbitraryLoadsInWebContent|NSAllowsArbitraryLoadsForMedia|NSAllowsArbitraryLoadsForLocalNetworking|NSExceptionDomains\["[^"]+"\]\.(NSExceptionAllowsInsecureHTTPLoads|NSTemporaryExceptionAllowsInsecureHTTPLoads|NSAllowsArbitraryLoads))' \
| egrep ' = (true|"true"|1|"1");$' > output.txt

Observation

The output shows the relevant ATS configuration keys and values found in the Info_reversed.plist file:

1
2
3
4
5
6
json.NSAppTransportSecurity.NSAllowsArbitraryLoads = true;
json.NSAppTransportSecurity.NSAllowsArbitraryLoadsForLocalNetworking = true;
json.NSAppTransportSecurity.NSAllowsArbitraryLoadsForMedia = true;
json.NSAppTransportSecurity.NSAllowsArbitraryLoadsInWebContent = true;
json.NSAppTransportSecurity.NSExceptionDomains["api.example.com"].NSExceptionAllowsInsecureHTTPLoads = true;
json.NSAppTransportSecurity.NSExceptionDomains["httpbin.org"].NSExceptionAllowsInsecureHTTPLoads = true;
 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
{
  "CFBundleName": "MASTestApp",
  "DTXcode": "2620",
  "DTSDKName": "iphoneos26.2",
  "DTSDKBuild": "23C53",
  "CFBundleDevelopmentRegion": "en",
  "CFBundleVersion": "1",
  "BuildMachineOSBuild": "25C56",
  "DTPlatformName": "iphoneos",
  "CFBundlePackageType": "APPL",
  "CFBundleShortVersionString": "1.0",
  "CFBundleSupportedPlatforms": [
    "iPhoneOS"
  ],
  "UIApplicationSupportsIndirectInputEvents": true,
  "UILaunchScreen": {
    "UILaunchScreen": {}
  },
  "UISupportedInterfaceOrientations~iphone": [
    "UIInterfaceOrientationPortrait",
    "UIInterfaceOrientationLandscapeLeft",
    "UIInterfaceOrientationLandscapeRight"
  ],
  "NSAppTransportSecurity": {
    "NSAllowsArbitraryLoads": true,
    "NSExceptionDomains": {
      "httpbin.org": {
        "NSExceptionMinimumTLSVersion": "TLSv1.1",
        "NSExceptionAllowsInsecureHTTPLoads": true,
        "NSIncludesSubdomains": true
      },
      "api.example.com": {
        "NSExceptionAllowsInsecureHTTPLoads": true,
        "NSExceptionRequiresForwardSecrecy": false,
        "NSIncludesSubdomains": true,
        "NSTemporaryExceptionMinimumTLSVersion": "TLSv1.0"
      }
    },
    "NSAllowsArbitraryLoadsInWebContent": true,
    "NSAllowsArbitraryLoadsForMedia": true,
    "NSAllowsArbitraryLoadsForLocalNetworking": true
  },
  "CFBundleInfoDictionaryVersion": "6.0",
  "CFBundleExecutable": "MASTestApp",
  "DTCompiler": "com.apple.compilers.llvm.clang.1_0",
  "UIRequiredDeviceCapabilities": [
    "arm64"
  ],
  "MinimumOSVersion": "17.1.1",
  "CFBundleIdentifier": "org.owasp.mastestapp.MASTestApp-iOS",
  "UIDeviceFamily": [
    1,
    2
  ],
  "DTPlatformVersion": "26.2",
  "DTXcodeBuild": "17C52",
  "LSRequiresIPhoneOS": true,
  "UIApplicationSceneManifest": {
    "UIApplicationSupportsMultipleScenes": true,
    "UISceneConfigurations": {}
  },
  "UISupportedInterfaceOrientations~ipad": [
    "UIInterfaceOrientationPortrait",
    "UIInterfaceOrientationPortraitUpsideDown",
    "UIInterfaceOrientationLandscapeLeft",
    "UIInterfaceOrientationLandscapeRight"
  ],
  "DTPlatformBuild": "23C53"
}

Evaluation

The test fails because several ATS settings are set to true, which disables ATS globally and allows cleartext HTTP traffic to any domain. Specifically, the following settings are misconfigured:

  • NSAllowsArbitraryLoadsForLocalNetworking = true allows cleartext traffic on local networks.
  • NSAllowsArbitraryLoadsForMedia = true allows cleartext traffic for media resources.
  • NSAllowsArbitraryLoadsInWebContent = true allows cleartext traffic in WebViews.
  • Domain-specific exceptions for api.example.com and httpbin.org also allow insecure HTTP loads.

Note that even though NSAllowsArbitraryLoads = true is present, it is ignored because NSAllowsArbitraryLoadsForLocalNetworking, NSAllowsArbitraryLoadsForMedia, and NSAllowsArbitraryLoadsInWebContent are also present (regardless of their values), which take precedence.

Context Considerations:

If you reverse the app binary, you will find that its code make a HTTP request to http://httpbin.org/get using URLSession, which is affected by the ATS exceptions.

  • The connection to httpbin.org is only allowed due to the domain-specific exception and not because of the global NSAllowsArbitraryLoads setting.
  • There are no connections to api.example.com, so the domain-specific exceptions for it does not have an effect in this case. Regardless, having such exceptions is still a misconfiguration and should be avoided.
  • The app does not use WebViews or media resources, so the corresponding ATS exceptions (NSAllowsArbitraryLoadsInWebContent and NSAllowsArbitraryLoadsForMedia) do not have an effect in this case. Regardless, having such exceptions is still a misconfiguration and should be avoided.
  • The app does not connect to local network resources, so the corresponding ATS exception (NSAllowsArbitraryLoadsForLocalNetworking) does not have an effect in this case. Regardless, having such an exception is still a misconfiguration and should be avoided.