# Buggy code
def check_transport_security(p_list):
    """Check info.plist for insecure connection configurations."""
    logger.info("Checking for Insecure Connections")
    ats = []
    if "NSAppTransportSecurity" in p_list:
        ats_dict = p_list["NSAppTransportSecurity"]
        if ats_dict.get("NSAllowsArbitraryLoads"):
            ats.append(
                {
                    "issue": ("App Transport Security AllowsArbitraryLoads is allowed"),
                    "status": "insecure",
                    "description": (
                        "App Transport Security restrictions are disabled "
                        "for all network connections. Disabling ATS means that "
                        "unsecured HTTP connections are allowed. HTTPS "
                        "connections are also allowed, and are still subject "
                        "to default server trust evaluation. However, "
                        "extended security checks like requiring a minimum "
                        "Transport Layer Security (TLS) protocol version—are "
                        "disabled. This setting is not applicable to domains "
                        "listed in NSExceptionDomains."
                    ),
                }
            )
        if ats_dict.get("NSAllowsArbitraryLoadsForMedia"):
            ats.append(
                {
                    "issue": "Insecure media load is allowed",
                    "status": "insecure",
                    "description": (
                        "App Transport Security restrictions are disabled for "
                        "media loaded using the AVFoundation framework, "
                        "without affecting your URLSession connections. "
                        "This setting is not applicable to domains "
                        "listed in NSExceptionDomains."
                    ),
                }
            )
        if ats_dict.get("NSAllowsArbitraryLoadsInWebContent"):
            ats.append(
                {
                    "issue": "Insecure WebView load is allowed",
                    "status": "insecure",
                    "description": (
                        "App Transport Security restrictions are disabled for "
                        "requests made from WebViews without affecting your "
                        "URLSession connections. This setting is not applicable "
                        "to domains listed in NSExceptionDomains."
                    ),
                }
            )
        if ats_dict.get("NSAllowsLocalNetworking"):
            ats.append(
                {
                    "issue": "Insecure local networking is allowed",
                    "status": "insecure",
                    "description": (
                        "App Transport Security restrictions are disabled for "
                        "requests made from local networking "
                        "without affecting your "
                        "URLSession connections. This setting is not applicable "
                        "to domains listed in NSExceptionDomains."
                    ),
                }
            )

        # NS Domain Exceptions

        exception_domains = ats_dict.get("NSExceptionDomains")
        if exception_domains:
            for domain, config in exception_domains.items():
                old_exp = "NSTemporaryExceptionAllowsInsecureHTTPLoads"
                if config.get(
                    "NSExceptionAllowsInsecureHTTPLoads", False
                ) or config.get(old_exp, False):
                    findings = {
                        "issue": (
                            "Insecure communication to {} is allowed".format(domain)
                        ),
                        "status": "insecure",
                        "description": (
                            "NSExceptionAllowsInsecureHTTPLoads allows "
                            "insecure HTTP loads to {}, "
                            "or to be able to loosen the "
                            "server trust evaluation "
                            "requirements for HTTPS "
                            "connections to the domain.".format(domain)
                        ),
                    }
                    ats.append(findings)

                if config.get("NSIncludesSubdomains", False):
                    findings = {
                        "issue": (
                            "NSIncludesSubdomains set to TRUE for {}".format(domain)
                        ),
                        "status": "insecure",
                        "description": (
                            "NSIncludesSubdomains applies the ATS exceptions "
                            "for the given domain to all "
                            "subdomains as well. "
                            "For example, the ATS exceptions in the "
                            "domain exception dictionary apply to {}, "
                            "as well as math.{}, history.{}, and so on. "
                            "Otherwise, if the value is NO, the exceptions "
                            "apply only to "
                            "{}.".format(domain, domain, domain, domain)
                        ),
                    }
                    ats.append(findings)
                old_tls = "NSTemporaryExceptionMinimumTLSVersion"
                inc_min_tls = config.get(
                    "NSExceptionMinimumTLSVersion", None
                ) or config.get(old_tls, None)
                if inc_min_tls in ["TLSv1.0", "TLSv1.1"]:
                    findings = {
                        "issue": (
                            "NSExceptionMinimumTLSVersion set to {} on {}".format(
                                inc_min_tls, domain
                            )
                        ),
                        "status": "insecure",
                        "description": (
                            "The minimum Transport Layer "
                            "Security (TLS) version "
                            "for network connections sent to {} "
                            "is set to {}. This version is deemed "
                            "to be insecure".format(domain, inc_min_tls)
                        ),
                    }
                    ats.append(findings)

                elif inc_min_tls == "TLSv1.2":
                    findings = {
                        "issue": (
                            "NSExceptionMinimumTLSVersion set to {} on {}".format(
                                inc_min_tls, domain
                            )
                        ),
                        "status": "warning",
                        "description": (
                            "The minimum Transport Layer "
                            "Security (TLS) version "
                            "for network connections sent to {} "
                            "is set to {}. "
                            "This version is vulnerable to "
                            "attacks such as POODLE, FREAK, "
                            "or CurveSwap etc.".format(domain, inc_min_tls)
                        ),
                    }
                    ats.append(findings)

                elif inc_min_tls == "TLSv1.3":
                    findings = {
                        "issue": (
                            "NSExceptionMinimumTLSVersion set to {} on {}".format(
                                inc_min_tls, domain
                            )
                        ),
                        "status": "secure",
                        "description": (
                            "The minimum Transport Layer "
                            "Security (TLS) version "
                            "for network connections sent to {} "
                            "is set to {}.".format(domain, inc_min_tls)
                        ),
                    }
                    ats.append(findings)

                elif inc_min_tls is None:
                    pass

                else:
                    findings = {
                        "issue": (
                            "NSExceptionMinimumTLSVersion set to {} on {}".format(
                                inc_min_tls, domain
                            )
                        ),
                        "status": "info",
                        "description": (
                            "The minimum Transport Layer "
                            "Security (TLS) version "
                            "for network connections sent to {} "
                            "is set to {}.".format(domain, inc_min_tls)
                        ),
                    }
                    ats.append(findings)
                old_fwd = "NSTemporaryExceptionRequiresForwardSecrecy"
                if config.get("NSExceptionRequiresForwardSecrecy", False) or config.get(
                    old_fwd, False
                ):
                    findings = {
                        "issue": (
                            "NSExceptionRequiresForwardSecrecy "
                            "set to YES"
                            " for {}".format(domain)
                        ),
                        "status": "secure",
                        "description": (
                            "NSExceptionRequiresForwardSecrecy "
                            "limits the accepted ciphers to "
                            "those that support perfect "
                            "forward secrecy (PFS) through the "
                            "Elliptic Curve Diffie-Hellman "
                            "Ephemeral (ECDHE) key exchange. "
                            "Set the value for this key to NO to override "
                            "the requirement that a server must support "
                            "PFS for the given domain. This key is optional. "
                            "The default value is YES, which limits the "
                            "accepted ciphers to those that support "
                            "PFS through Elliptic Curve Diffie-Hellman "
                            "Ephemeral (ECDHE) key exchange."
                        ),
                    }
                    ats.append(findings)

                if config.get("NSRequiresCertificateTransparency", False):
                    findings = {
                        "issue": (
                            "NSRequiresCertificateTransparency"
                            " set to YES for {}".format(domain)
                        ),
                        "status": "secure",
                        "description": (
                            "Certificate Transparency (CT) is a protocol "
                            "that ATS can use to identify "
                            "mistakenly or maliciously "
                            "issued X.509 certificates. "
                            "Set the value for the "
                            "NSRequiresCertificateTransparency "
                            "key to YES to require that for a given domain, "
                            "server certificates are supported by valid, "
                            "signed CT timestamps from at least "
                            "two CT logs trusted by Apple. "
                            "This key is optional. The default value is NO."
                        ),
                    }
                    ats.append(findings)

    return ats


# Traceback (AttributeError)
__  __       _    ____  _____       _____  ___
|  \/  | ___ | |__/ ___||  ___|_   _|___ / / _ \
| |\/| |/ _ \| '_ \___ \| |_  \ \ / / |_ \| | | |
| |  | | (_) | |_) |__) |  _|  \ V / ___) | |_| |
|_|  |_|\___/|_.__/____/|_|     \_/ |____(_)___/

[INFO] 02/Apr/2020 15:43:11 - Mobile Security Framework v3.0.6 Beta
REST API Key: 618941ebdec42a7f519ed5dca40d9b3c5f17606ca6142fc2fc725f36cce06c40
[INFO] 02/Apr/2020 15:43:11 - OS: Linux
[INFO] 02/Apr/2020 15:43:11 - Platform: Linux-4.4.0-173-generic-x86_64-with-Ubuntu-18.04-bionic
[INFO] 02/Apr/2020 15:43:11 - Dist: ubuntu 18.04 bionic
[INFO] 02/Apr/2020 15:43:11 - MobSF Basic Environment Check
[INFO] 02/Apr/2020 15:43:11 - Checking for Update.
[INFO] 02/Apr/2020 15:43:12 - No updates available.
[INFO] 02/Apr/2020 15:44:21 - MIME Type: application/octet-stream FILE: ziaanalytics.ipa
[INFO] 02/Apr/2020 15:44:22 - Performing Static Analysis of iOS IPA
[INFO] 02/Apr/2020 15:44:22 - iOS Static Analysis Started
[INFO] 02/Apr/2020 15:44:22 - iOS Binary (IPA) Analysis Started
[INFO] 02/Apr/2020 15:44:22 - Generating Hashes
[INFO] 02/Apr/2020 15:44:22 - Extracting IPA
[INFO] 02/Apr/2020 15:44:22 - Unzipping
[INFO] 02/Apr/2020 15:44:25 - Get Files, BIN Plist -> XML, and Normalize
[INFO] 02/Apr/2020 15:44:25 - iOS Info.plist Analysis Started
[INFO] 02/Apr/2020 15:44:25 - Finding Info.plist in iOS Binary
[INFO] 02/Apr/2020 15:44:25 - Checking Permissions
[INFO] 02/Apr/2020 15:44:25 - Checking for Insecure Connections
[ERROR] 02/Apr/2020 15:44:25 - Reading from Info.plist
Traceback (most recent call last):
File "/root/Mobile-Security-Framework-MobSF/StaticAnalyzer/views/ios/plist_analysis.py", line 99, in plist_analysis
plist_info['inseccon'] = check_transport_security(plist_obj)
File "/root/Mobile-Security-Framework-MobSF/StaticAnalyzer/views/ios/app_transport_security.py", line 68, in check_transport_security
if (config.get('NSExceptionAllowsInsecureHTTPLoads', False)
AttributeError: 'str' object has no attribute 'get'
[ERROR] 02/Apr/2020 15:44:25 - Error Perfroming Static Analysis
Traceback (most recent call last):
File "/root/Mobile-Security-Framework-MobSF/StaticAnalyzer/views/ios/static_analyzer.py", line 99, in static_analyzer_ios
app_dict['appstore'] = app_search(infoplist_dict.get('id'))
AttributeError: 'NoneType' object has no attribute 'get'
[ERROR] 02/Apr/2020 15:44:25 - 'NoneType' object has no attribute 'get'
[ERROR] 02/Apr/2020 15:44:25 - Internal Server Error: /StaticAnalyzer_iOS/

# Fixed code
def check_transport_security(p_list):
    """Check info.plist for insecure connection configurations."""
    logger.info("Checking for Insecure Connections")
    ats = []
    if "NSAppTransportSecurity" in p_list:
        ats_dict = p_list["NSAppTransportSecurity"]
        if ats_dict.get("NSAllowsArbitraryLoads"):
            ats.append(
                {
                    "issue": ("App Transport Security AllowsArbitraryLoads is allowed"),
                    "status": "insecure",
                    "description": (
                        "App Transport Security restrictions are disabled "
                        "for all network connections. Disabling ATS means that "
                        "unsecured HTTP connections are allowed. HTTPS "
                        "connections are also allowed, and are still subject "
                        "to default server trust evaluation. However, "
                        "extended security checks like requiring a minimum "
                        "Transport Layer Security (TLS) protocol version—are "
                        "disabled. This setting is not applicable to domains "
                        "listed in NSExceptionDomains."
                    ),
                }
            )
        if ats_dict.get("NSAllowsArbitraryLoadsForMedia"):
            ats.append(
                {
                    "issue": "Insecure media load is allowed",
                    "status": "insecure",
                    "description": (
                        "App Transport Security restrictions are disabled for "
                        "media loaded using the AVFoundation framework, "
                        "without affecting your URLSession connections. "
                        "This setting is not applicable to domains "
                        "listed in NSExceptionDomains."
                    ),
                }
            )
        if ats_dict.get("NSAllowsArbitraryLoadsInWebContent"):
            ats.append(
                {
                    "issue": "Insecure WebView load is allowed",
                    "status": "insecure",
                    "description": (
                        "App Transport Security restrictions are disabled for "
                        "requests made from WebViews without affecting your "
                        "URLSession connections. This setting is not applicable "
                        "to domains listed in NSExceptionDomains."
                    ),
                }
            )
        if ats_dict.get("NSAllowsLocalNetworking"):
            ats.append(
                {
                    "issue": "Insecure local networking is allowed",
                    "status": "insecure",
                    "description": (
                        "App Transport Security restrictions are disabled for "
                        "requests made from local networking "
                        "without affecting your "
                        "URLSession connections. This setting is not applicable "
                        "to domains listed in NSExceptionDomains."
                    ),
                }
            )

        # NS Domain Exceptions

        exception_domains = ats_dict.get("NSExceptionDomains")
        if exception_domains:
            ats.append(
                {
                    "issue": "NSExceptionDomains",
                    "status": "info",
                    "description": ", ".join(exception_domains.keys()),
                }
            )
            for domain, config in exception_domains.items():
                if not isinstance(config, dict):
                    continue
                old_exp = "NSTemporaryExceptionAllowsInsecureHTTPLoads"
                if config.get(
                    "NSExceptionAllowsInsecureHTTPLoads", False
                ) or config.get(old_exp, False):
                    findings = {
                        "issue": (
                            "Insecure communication to {} is allowed".format(domain)
                        ),
                        "status": "insecure",
                        "description": (
                            "NSExceptionAllowsInsecureHTTPLoads allows "
                            "insecure HTTP loads to {}, "
                            "or to be able to loosen the "
                            "server trust evaluation "
                            "requirements for HTTPS "
                            "connections to the domain.".format(domain)
                        ),
                    }
                    ats.append(findings)

                if config.get("NSIncludesSubdomains", False):
                    findings = {
                        "issue": (
                            "NSIncludesSubdomains set to TRUE for {}".format(domain)
                        ),
                        "status": "insecure",
                        "description": (
                            "NSIncludesSubdomains applies the ATS exceptions "
                            "for the given domain to all "
                            "subdomains as well. "
                            "For example, the ATS exceptions in the "
                            "domain exception dictionary apply to {}, "
                            "as well as math.{}, history.{}, and so on. "
                            "Otherwise, if the value is NO, the exceptions "
                            "apply only to "
                            "{}.".format(domain, domain, domain, domain)
                        ),
                    }
                    ats.append(findings)
                old_tls = "NSTemporaryExceptionMinimumTLSVersion"
                inc_min_tls = config.get(
                    "NSExceptionMinimumTLSVersion", None
                ) or config.get(old_tls, None)
                if inc_min_tls in ["TLSv1.0", "TLSv1.1"]:
                    findings = {
                        "issue": (
                            "NSExceptionMinimumTLSVersion set to {} on {}".format(
                                inc_min_tls, domain
                            )
                        ),
                        "status": "insecure",
                        "description": (
                            "The minimum Transport Layer "
                            "Security (TLS) version "
                            "for network connections sent to {} "
                            "is set to {}. This version is deemed "
                            "to be insecure".format(domain, inc_min_tls)
                        ),
                    }
                    ats.append(findings)

                elif inc_min_tls == "TLSv1.2":
                    findings = {
                        "issue": (
                            "NSExceptionMinimumTLSVersion set to {} on {}".format(
                                inc_min_tls, domain
                            )
                        ),
                        "status": "warning",
                        "description": (
                            "The minimum Transport Layer "
                            "Security (TLS) version "
                            "for network connections sent to {} "
                            "is set to {}. "
                            "This version is vulnerable to "
                            "attacks such as POODLE, FREAK, "
                            "or CurveSwap etc.".format(domain, inc_min_tls)
                        ),
                    }
                    ats.append(findings)

                elif inc_min_tls == "TLSv1.3":
                    findings = {
                        "issue": (
                            "NSExceptionMinimumTLSVersion set to {} on {}".format(
                                inc_min_tls, domain
                            )
                        ),
                        "status": "secure",
                        "description": (
                            "The minimum Transport Layer "
                            "Security (TLS) version "
                            "for network connections sent to {} "
                            "is set to {}.".format(domain, inc_min_tls)
                        ),
                    }
                    ats.append(findings)

                elif inc_min_tls is None:
                    pass

                else:
                    findings = {
                        "issue": (
                            "NSExceptionMinimumTLSVersion set to {} on {}".format(
                                inc_min_tls, domain
                            )
                        ),
                        "status": "info",
                        "description": (
                            "The minimum Transport Layer "
                            "Security (TLS) version "
                            "for network connections sent to {} "
                            "is set to {}.".format(domain, inc_min_tls)
                        ),
                    }
                    ats.append(findings)
                old_fwd = "NSTemporaryExceptionRequiresForwardSecrecy"
                if config.get("NSExceptionRequiresForwardSecrecy", False) or config.get(
                    old_fwd, False
                ):
                    findings = {
                        "issue": (
                            "NSExceptionRequiresForwardSecrecy "
                            "set to YES"
                            " for {}".format(domain)
                        ),
                        "status": "secure",
                        "description": (
                            "NSExceptionRequiresForwardSecrecy "
                            "limits the accepted ciphers to "
                            "those that support perfect "
                            "forward secrecy (PFS) through the "
                            "Elliptic Curve Diffie-Hellman "
                            "Ephemeral (ECDHE) key exchange. "
                            "Set the value for this key to NO to override "
                            "the requirement that a server must support "
                            "PFS for the given domain. This key is optional. "
                            "The default value is YES, which limits the "
                            "accepted ciphers to those that support "
                            "PFS through Elliptic Curve Diffie-Hellman "
                            "Ephemeral (ECDHE) key exchange."
                        ),
                    }
                    ats.append(findings)

                if config.get("NSRequiresCertificateTransparency", False):
                    findings = {
                        "issue": (
                            "NSRequiresCertificateTransparency"
                            " set to YES for {}".format(domain)
                        ),
                        "status": "secure",
                        "description": (
                            "Certificate Transparency (CT) is a protocol "
                            "that ATS can use to identify "
                            "mistakenly or maliciously "
                            "issued X.509 certificates. "
                            "Set the value for the "
                            "NSRequiresCertificateTransparency "
                            "key to YES to require that for a given domain, "
                            "server certificates are supported by valid, "
                            "signed CT timestamps from at least "
                            "two CT logs trusted by Apple. "
                            "This key is optional. The default value is NO."
                        ),
                    }
                    ats.append(findings)

    return ats