App Transport Security in debug builds.

1 minute read

Since iOS 9, Apple has enforced best practices in the secure connections between your app and its back end, by adding something called “App Transport Security”, or “ATS” for short. ATS is on by default, and prevents accidental disclosure and provides secure default behavior by mandating that a network connection is over HTTPS, and by limiting the supported ciphers to a subset that is known to be secure, notably TLS 1.2 and so-called forward secrecy.

This is all great, but during development, when running a copy of your backend on your own laptop, you probably don’t have a real certificate from a trusted authority.

We can always override the default security feature by defining appropriate exception rules in Info.plist:

  • NSIncludesSubdomains
  • NSExceptionAllowsInsecureHTTPLoads
  • NSExceptionRequiresForwardSecrecy
  • NSExceptionMinimumTLSVersion
  • NSThirdPartyExceptionAllowsInsecureHTTPLoads
  • NSThirdPartyExceptionMinimumTLSVersion
  • NSThirdPartyExceptionRequiresForwardSecrecy

However, using exceptions is something we should be careful about. There’s a reason these rules are enforced by default, and we should only disable them when strictly necessary, and only for the smallest possible set of domains. But there is one exception: When running locally.

But how do you do this, without resolving to using a separate Info.plist file for debug builds?

Add a “Run script” build phase to your target, and paste the following script:

INFO_PLIST="${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"
PLISTBUDDY="/usr/libexec/PlistBuddy"

if [ "${CONFIGURATION}" == "Debug" ]; then
    $PLISTBUDDY -c "Add :NSAppTransportSecurity dict" "${INFO_PLIST}" || true
    $PLISTBUDDY -c "Add :NSAppTransportSecurity:NSAllowsArbitraryLoads bool true" "${INFO_PLIST}" || true
    $PLISTBUDDY -c "Set :NSAppTransportSecurity:NSAllowsArbitraryLoads true" "${INFO_PLIST}"
else
    $PLISTBUDDY -c "Delete :NSAppTransportSecurity:NSAllowsArbitraryLoads" "${INFO_PLIST}" || true
fi

ALLOWS_ARBITRARY_LOADS_ENABLED=$($PLISTBUDDY -c "Print :NSAppTransportSecurity:NSAllowsArbitraryLoads" "${INFO_PLIST}")
if [ "${ALLOWS_ARBITRARY_LOADS_ENABLED}" == "true" ]; then
  echo "warning: ATS is disbaled. :NSAppTransportSecurity:NSAllowsArbitraryLoads set to true. This is insecure and should not be used in release builds."
fi

It checks to see if you’re building in the Debug configuration, and if so, inserts an appropriate exception key to your Info.plist file. It does not touch the source file, but only the build output. If you’re not building in Debug mode, the key is deleted if it exists. It also outputs a warning if the exception is in place:

Tags:

Updated:

Leave a Comment