Search code examples
iosapp-transport-security

Do I need to use NSExceptionDomains, or can I just disable App Transport Security completely?


I'm working on an app that streams a number of remote live videos. These live videos vary in URLs and most of them use HTTP not HTTPS.

Are there any drawbacks to disabling App Transport Security completely by setting AllowArbitraryLoads to YES? Or should I use NSExceptionDomains? Are there any other options that would provide the most security for the app users, while ensuring that the app does not run into problems when trying to communicate with the media servers.


Solution

  • While disabling ATS entirely with NSAllowsArbitraryLoads is often the solution given and accepted here on SO, it comes with some consequences that a developer should be aware of. First, as of right now (Aug 2017), Apple is allowing developers to use that setting to disable ATS as they choose. However, Apple has stated that they will start requiring developers to provide justification for turning off ATS completely with that key. Apple originally planned to start enforcing the need for justification in Jan 2017, but pushed it back indefinitely. To me, it is a risk to developers to continue to use the NSAllowsArbitraryLoads setting as when Apple starts enforcing the new policy, developers may be unable to submit critical fixes for their apps to the app store.

    Specifically for your question around streaming videos, there are a couple of options you could use instead:

    NSAllowsArbitraryLoadsForMediaContent

    Starting in iOS 10, Apple has offered a new key NSAllowsArbitraryLoadsForMediaContent for excluding media content from the ATS requirements. That key (along with the similar NSAllowsArbitraryLoadsForWebContent) would not require justification under Apple's guidelines.

    However, since this key was only added in iOS 10, it poses a problem if your app needs to support running on iOS 9 devices. Fortunately, Apple has provided a way to do this as well. To support iOS 9 and iOS 10+ devices, you would add both NSAllowsArbitraryLoadsForMediaContent and NSAllowsArbitraryLoads to your plist. Since iOS9 doesnt know of the NSAllowsArbitraryLoadsForMediaContent, it only sees / cares about the NSAllowsArbitraryLoads key, and would disable all ATS compliance checks for the iOS 9 devices. because iOS10 knows about the new key, it would ignore the 'NSAllowsArbitraryLoads' and only disable ATS compliance checking for media streams.

    Because this is Apple's recommended approach if you need to support iOS9 devices, if you do need to provide justification at some point in the future, you can simply state it is the Apple recommended approach to support non-https streaming of media on iOS 9 devices. At least they will see that you are trying to allow ATS to provide it's services.

    NSExceptionDomains

    If you do know of all the domains that your media resides on that don't support all the ATS requirements, and the NSAllowsArbitraryLoadsForMediaContent approach doesn't work for you, I would recommend using NSExceptionDomains next. Again, it shows Apple that you are trying to limit the amount of exposure your app users have to insecure server connections. If you do need to provide Apple justification later, you can simply let them know that the domains are not under your control, but that the rest of your app's communication are still protected by ATS compliance checks.

    NSAllowsArbitraryLoads

    At this point, there are some apps that might need to use this setting. But those should be basically limited to apps that allow user entered servers (where the developer doesn't know what servers the app might need to communicate with. Those apps are very rare. Most apps are simply setting this because they got an error in development starting in iOS9, and read some SO answer that sais the error goes away if you set the flag. Sadly, I think the volume of apps blindly following that advice is likely what led to Apple trying to impose the justification process.

    And even if you use the NSAllowsArbitraryLoads setting, it is best practices to also use NSExecption domains to add exceptions to *turn ATS compliance checks back on** for domains you control that are ATS compliant. Then at least Apple will know that you are securing the connections that you control.

    So only use NSAllowsArbitraryLoads as a last resort for an app that you truly cannot know of the server connections.