I’ve recently noticed a spike in questions from our customers — and specifically security analysts — about App Transport Security (ATS), or NSAppTransportSecurity, for iOS apps. ATS is a critical security practice for our customers in financial services and other regulated industries. A lot of ATS documentation already exists, but questions persist. A core part of the NowSecure mission is helping organizations maximize the security of their mobile apps. So, as a security analyst myself, I wanted to write-up a quick guide to ATS — for security analysts, by a security analyst — to cover topics such as:

  • NSAllowsArbitraryLoads and other ATS exceptions
  • Auditing and evaluating an app’s ATS implementation
  • Why ATS is a crucial security measure
  • Clues offered by ATS configurations for black-box testing
  • A quick summary of some ATS updates coming in iOS 11

ATS brings much-needed client-side protection to iOS apps, enforces stronger ciphers, and prevents an app’s use of HTTP and insecure HTTPS traffic — a priority for most security analysts I talk to.  By helping mitigate the risks of insecure connections, ATS can be used within iOS apps to enforce server-side protections.

App Transport Security (ATS) overview

ATS allows mobile app developers to implement a network security policy for their apps on the client side by prohibiting the use of cleartext protocols, invalid self-signed certificates for TLS connections, and weak cipher suites. These policies are configured in an app’s Info.plist file and were introduced in iOS 9.

Apple originally announced that apps published to the app store would need to implement ATS by January 1, 2017.  As the deadline approached however, Apple postponed it indefinitely and has not yet announced a new due date.

In December of 2016, we found 80% of the 201 most downloaded apps on the Apple® App Store® globally opted out of ATS by setting the NSAllowsArbitraryLoads key to YES. More recently, we used the unique analysis capabilities of our NowSecure Intelligence™ product, to analyze 12,000 iOS apps and their use of ATS. We found that by using the NSArbitraryLoads exception, roughly 63% of the top iOS apps opt out of ATS, meaning in some cases it’s possible that those apps send sensitive data insecurely over HTTP.

Put another way, our findings suggest that 37% of those 12,000 iOS apps use default ATS (i.e., they don’t opt out). That paints a slightly more promising picture than our previous studies, but a lot of app developers still have work to do. Opting out of ATS conflicts with good security practices.

If the security benefits of ATS aren’t enough to convince your development team to get to work on implementing ATS properly, let them know that Apple will eventually announce another deadline. In addition, a number of the ATS keys I describe below will set off additional App Store review of the app in question, and their use will need to be justified to Apple as part of submitting an app to the store. Those keys include:

  • NSAllowsArbitraryLoads
  • NSAllowsArbitraryLoadsForMedia
  • NSAllowsArbitraryLoadsInWebContent
  • NSExceptionAllowsInsecureHTTPLoads
  • NSExceptionMinimumTLSVersion

There’s no time like the present to prepare. By enforcing ATS, Apple requires developers and security analysts to audit the endpoints that support the functionality of their apps to make those endpoints, their apps, and associated connections more secure. I think this auditing is one of the real benefits of ATS.

Auditing ATS implementations

Part of Apple’s enforcement of ATS requires apps to justify any exceptions. Apple wants to make sure a developer has a good reason for opting out. When an app uses an exception, it can diminish the security of an app if it’s misconfigured. Security analysts tasked with identifying security issues in a mobile app need to understand exceptions in order to properly audit them.

Exceptions, also known as keys, can indicate information about an application before dynamic testing begins.  While it’s important to apply a testing regimen that covers every aspect of an iOS app regardless of what protections are applied, analysts can use these keys to identify areas they might want to give special attention to during a mobile app penetration test.

Once you have a binary, you can start testing the ATS configuration as soon as you’ve downloaded the .ipa.  The commands below also apply to binaries downloaded from the Apple® App Store® that use FairPlay® encryption. To view the ATS configuration of your app, use the following commands:

unzip <appName>.ipa
cd Payload/<BundleName>.app/
plutil -convert xml1 Info.plist
open Info.plist

The .ipa is now unzipped and the Info.plist file is converted into a readable format and opened.  Now, locate the “App Transport Security Settings,” and there you will find the current ATS configuration which will look something like this:

NSAppTransportSecurity : Dictionary {
    NSAllowsArbitraryLoads : Boolean
    NSAllowsArbitraryLoadsForMedia : Boolean
    NSAllowsArbitraryLoadsInWebContent : Boolean
    NSAllowsLocalNetworking : Boolean
    NSExceptionDomains : Dictionary {
        <domain-name-string> : Dictionary {
            NSIncludesSubdomains : Boolean
            NSExceptionAllowsInsecureHTTPLoads : Boolean
            NSExceptionMinimumTLSVersion : String
            NSExceptionRequiresForwardSecrecy : Boolean   
            NSRequiresCertificateTransparency : Boolean
        }
    }
}

There you’ll see the app’s ATS primary and subkeys.  Each key helps developers configure the app’s ATS implementation and make exceptions for domains that can’t support ATS.

NSAppTransportSecurity configuration keys, subkeys, and exceptions

To help security analysts understand the various ATS exceptions and how they affect the security posture of an iOS app, I’ve described them below.

NSAllowArbitraryLoads

The NSAllowArbitraryLoads key is set to NO by default. Setting the key to YES will opt-out of ATS and its associated security benefits.  If in testing an app you find this key set to YES, verify why the developers decided to opt out. In addition, check into the NSExceptionDomains exception and whether any domains are listed there. We’ve encountered a number of cases where developers have opted out of ATS globally, but then opted in only for certain domains by listing an exception domain. A better approach is to enable ATS globally, and only opt out for certain domains if absolutely necessary (more on that in the NSExceptionDomains section below).

If they key is set to YES, spend time verifying:

  • The ciphers used for the app’s backend connections (and that they’re strong)
  • The protocols used to send and retrieve data (and that they’re secure)
  • Whether the app has any downgrade vulnerabilities
  • Whether the app validates certificates used for TLS connections

While you should perform testing in these areas regardless of the ATS configuration, a developer setting this key to YES increases risks in these areas.

NSAllowsLoadsForMedia

This exception is for media content protected by digital rights management (DRM) or encryption.  When the NSAllowsLoadsForMedia key is set to YES, ATS is disabled for content sent using the AVFoundation framework (typically the case with apps that include audiovisual recording, editing, or playback functionality). If making sure your app’s media content is sent securely over the network is important to you and this key is enabled, confirm that media sent by the app is free of sensitive content and protected using DRM or encryption. While it’s best practice to implement these protections even if content is transmitted over HTTPS, capturing the transmitted content over HTTP or other insecure protocols is trivial.

NSAllowsArbitraryLoadsInWebContent

By default, NSAllowsArbitraryLoadsInWebContent is set to NO. When the key is set to YES, ATS is disabled for webview requests. You would usually see this exception if a webview is used within the app. In that case, you’ll want to assess whether the webview sends sensitive data. That’s because with the key enabled, data can be sent over HTTP or other insecure protocols or connections.

Using webviews can introduce vulnerabilities into an app, so it’s crucial to verify their security. For example, webviews can be vulnerable to a number of common web-based vulnerabilities such as SQL injection, cross-site request forgery, and cross-site scripting attacks.  For additional security information about using webviews, check out our webviews best practices.

NSAllowsLocalNetworking

NSAllowsLocalNetworking is set to NO by default. Setting it to YES will disable ATS for connections over a local network. Typical use cases for this exception might be apps that connect to a local hardware device in an Internet-of-Things (IoT) scenario. Apps that facilitate local peer-to-peer connections may also use this exception. If you run into this exception when testing an app, replicate the environment within which this local connection would take place to check for sensitive data sent over the local network in an insecure method. Even if an app connects to a local device, a best security practice is to use a TLS connection between those endpoints.

NSExceptionDomains and subkeys

NSExceptionDomains

Using the NSExceptionDomains key, developers can configure ATS exceptions on a domain-by-domain basis.  Security analysts should note that ATS subkeys within NSExceptionDomains supersede other primary keys.  For example, if an app loads media from a specific domain and both the NSAllowsLoadsForMedia exception and a NSExceptionDomains configuration is used for that particular domain, the NSExceptionDomains subkey parameters supersede the NSAllowsLoadsForMedia key parameters.

Security analysts should also note that without additional configuration using the subkeys underneath the primary NSExceptionDomain key, connections between the app and a listed domain will enforce ATS on the connection (even with NSAllowsArbitraryLoads set to YES). Put another way — if an exception domain is listed without any configuration of the subkeys, that domain will receive full ATS protection, even if the NSAllowsArbitraryLoads is set to YES.  This can complicate analysis because a developer can shut off ATS globally but turn it on for specific domains by listing them within the NSExceptionDomains key.

Some developers are tempted to opt-out globally and opt-in for specific domains. However, a better practice is to leave ATS globally enabled for better protection coverage and only exempt domains your organization doesn’t control (the intended use case for the NSExceptionDomain key). And even then, only if necessary. Explain to your development team that coding logical ATS subkey exceptions will simplify the justification used for each exception and make life easier in the long run when Apple enforces a deadline.  ATS should be enabled globally, and exceptions to ATS created through the NSExceptionDomains subkeys.

If an app you’re testing uses NSExceptionDomains and sets NSAllowsArbitraryLoads to YES, make sure you’re auditing the connections between the app and back-end services. Ideally, the app is only connecting to domains listed in the top-level NSExceptionDomains key, without any further configuration in the subkeys (again, effectively opting-into ATS for specific domains).  If there are connections to other domains not in that list, ATS will not be enforced for those domains.

NSIncludesSubdomains

By default this key is set to NO. When it’s set to YES, any ATS configuration enabled for a particular domain will carry through for all subdomains of the exception domain. And, if you set an exception domain, but don’t configure any additional subkeys beyond the NSIncludesSubdomains key, the exception domain and its subdomains will use ATS. If you’re testing an app that has this key enabled, approach any subdomains in the same way you would the main domain. In addition, if ATS is globally disabled, and this key is set to NO, confirm that the subdomains are not in use in the app.

NSExceptionAllowsInsecureHTTPLoads

By default this key is set to NO. When this key is set to YES, the app will be allowed to send HTTP traffic to that domain.  If you see this key set to YES, make sure to take a look at what information is being sent over the network. It may be sent insecurely over HTTP. If information must be sent over HTTP, at least make sure the information sent isn’t sensitive and that all connections are secure.

NSExceptionMinimumTLSVersion

This key allows developers to lower the minimum accepted version of TLS.  By default, TLS 1.2 and higher are the accepted versions.  If you see this exception in place, you will want to verify the TLS configuration of that endpoint, the reason why it needed to be lowered, and that it doesn’t violate your own organization’s compliance requirements.

NSExceptionRequiresForwardSecrecy

By default this key is set to YES.  If this key is set to NO it will disable perfect forward secrecy.  Similar to theNSExceptionMinimumTLSVersion key, if you encounter this key in an app you’re testing, verify the TLS configuration of the endpoint, the reason why it needs to be lowered, and your own organization’s compliance requirements.

NSRequiresCertificateTransparency

By default this key is set to NO. If the key is set to YES, it will require a Certificate Transparency timestamp on the domain’s certificate.  Certificate Transparency is a Google project aimed at making the SSL certificate system more secure.  If your organization or the domain in question supports Certificate Transparency, you’ll want to enable this.  Certificate Transparency helps audit against rogue Certificate Authorities (CAs) and malicious certificates, and it can help prevent man-in-the-middle attacks by notifying DevOps teams if their certificate has been compromised. When this key is enabled, the certificate checks associated with Certificate Transparency will be performed before a connection is made.

Determining whether your app’s endpoints can support ATS

If you started your analysis and discovered right off the bat that ATS was not being used by your app or is misconfigured, you’re not alone. As I mentioned above, we discovered that approximately 63% of apps on the app store currently opt-out of ATS using the NSAllowsArbitraryLoads key.

If you’re interested in enabling ATS on your app, start small.  First, check whether your endpoints are already compatible with ATS. Do that using your MacOS device and the /usr/bin/nscurl --ats-diagnostics --verbose <https://yourdomain.com> Xcode command to verify if your endpoint is currently compatible.

Here you’ll see example output from that command (click to expand):

/usr/bin/nscurl --ats-diagnostics --verbose https://example.com
Starting ATS Diagnostics

Configuring ATS Info.plist keys and displaying the result of HTTPS loads to https://example.com.
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 example.com

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

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

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

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

Configuring PFS exceptions for example.com

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

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

Configuring PFS exceptions and allowing insecure HTTP for example.com

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

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

Configuring TLS exceptions with PFS disabled for example.com

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

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

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

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

Configuring TLS exceptions with PFS disabled and insecure HTTP allowed for example.com

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

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

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

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

You might be surprised to find that many of the services used by your app can already support ATS. For example, the Facebook Audience Network offers full support for ATS (Facebook ATS Documentation). For a great example of how to configure an app’s Amazon Web Services (AWS) environment for ATS, take a look at this ATS how-to guide from the AWS Security Blog.

For more specific details about ATS implementation in iOS apps, check out the available Apple documentation.

Keeping an eye out for iOS 11 ATS updates

Apple will soon release iOS 11 and some ATS updates are expected as a part of that:

  • TLSv1.3 will receive preliminary support
  • 3DES will be removed from the approved list of ciphers
  • Certificates signed with SHA1 will no longer be accepted
  • Certificates signed with RSA keys must have 2048-bit key lengths or larger

For more information about these updates and ATS, see the WWDC 2017 session “Your Apps and Evolving Network Security Standards.” If you’re interested in iOS 11 security updates beyond ATS, register for our webinar “Android ‘O’ & iOS 11 security updates: What you need to know” scheduled for September 14.

Also keep your eye out for enhanced Certificate Transparency and Online Certificate Status Protocol (OCSP) stapling support — both of these technologies help verify that your certificate hasn’t been compromised. Finally, don’t be surprised if Apple ends support for AES-CBC in ATS in the next year or so. The cipher-block chaining (CBC) mode of encryption has been shown to make cryptographic systems vulnerable to attacks such as a padding oracle attack.

Conclusion: Remember, ATS is not a silver bullet

ATS is a client-side security measure and does not replace server-side security. Client-side security can be bypassed when an attacker has physical access to a device. So while ATS protects iOS apps and their users by helping prevent SSL downgrade attacks and the use of weak ciphers, developers and DevOps teams still need to secure an app’s back-end — e.g., by implementing HTTP Strict Transport Security (HSTS), disabling weak ciphers, etc. Client-side security reinforces server-side security, and is just one layer of a defense-in-depth approach to securing a mobile app.

To learn how NowSecure and the NowSecure Platform can help you manage mobile app security risk and more specifically audit your app’s ATS configurations, e-mail us at [email protected] or fill out our contact form.

What to read next:

Tony Ramirez

linkedin icon twitter icon

Senior Application Security Analyst

As mobile security analyst at NowSecure, Tony Ramirez consults with customers and performs mobile app penetration testing of iOS and Android apps as part of the NowSecure Services team. Tony holds a master's degree in cyber forensics and security from Illinois Institute of Technology.