Developing an application involves much more than the written code. Even if it was possible to build an (almost) bug-free code, if the app:
- depends on a server anywhere on the internet
- stores data in local storage devices
- or saves code bases in a repository cloud
there are potential vulnerabilities for a attacker to take advantage, as these interactions go beyond the code itself.
The aim of this post is to expose different techniques in order to minimize the chances for an attacker to break our security, as well as our clients’ and users’ security.
Note: This is not intended to be an extensive guide implementing each technique, however, this is a guide explaining what we can and should manage when developing an iOS application.
Enable Application Transport Security:
With the launch of iOS 9 and OS X El Capitan, Apple has introduced App Transport Security, which enforces developers to use secure network connections. This change implies that every connection the application makes must use HTTPS protocol and TLS 1.2.
In other words, our application cannot communicate with a server using a non-secure connection, such as HTTP, unless it is explicitly indicated. As this was a breaking change, Apple provided an easy way to master this new requirement by adding exceptions or disabling it in the plist file.
Nevertheless, it is strongly recommended not to bypass this restriction, and instead, use secure connections in our apps to avoid potential (and easy) attacks.
- Configuring App Transport Security Exceptions in iOS 9 and OSX
- 10.11Working with Apple’s Application Transport
- NSAppTransportSecurity Apple’s official documentation
Once ATS is enabled, the second step to increase our apps security consists in enabling SSL Pinning.
SSL Pinning is a technique that allows us to deal with an attack called Man in the Middle. SSL is based on the certificate’s “chain of trust”. When the communication starts, the client checks if the received server’s SSL certificate is trusted by any SSL Certificate Authority.
We can use SSL Pinning to ensure that the app communicates only with the designated server itself. This is done by saving the target server’s SSL certificate inside the app bundle.
SSL Pinning has a visible disadvantage, not related to the security itself: the app must be updated whenever the server’s SSL key is changed, due to expiration and other reasons.
- How to make your iOS apps more secure with SSL Pinning
- Enforcing Stricter Server Trust Evaluation Apple’s official documentation
Keychain vs. NSUserDefaults for storing sensitive data:
NSUserDefaults is a class that provides simple storage for different data types. Generally, it is used for small bits of information that need to be persisted between app launches or device restarts.
It is important to keep in mind that NSUserDefaults stores that information as plain text in a plist file, which means that everyone with access to the device can open or copy the file and read the information without encryption.
So, what happens if we need to store sensitive information? Use Keychain: an encrypted container to store passwords for multiple applications and secure services. Apple uses keychain as the password management system in Mac OS and iOS.
In the links below there’s detailed information with example code for using Keychain. It’s very simple to migrate from NSUserDefaults in the case that your application actually uses NSUserDefaults for sensitive data.
- NSUserDefaults is not for sensitive data
- Using the iOS Keychain
- NSUserDefaults Apple’s official documentation
Keeping private info out of the repository:
Secret information should not be part of the code base, instead, it must be located in a configuration file outside version control, or added as environment variables.
Additionally, the right information should be chosen automatically depending upon which target configuration you are currently working on.
A good way to manage this kind of situation is to use xCode configuration files, called xcconfig files.
Essentially, we can set our private properties in xcconfig files (one for each target configuration we have in for the project). Then, in our code, we can access them as if they were in the project user defined properties, in which xCode will automatically load the properties corresponding to the target configuration we are running the application on.
Next time you are developing an iOS application, make sure to keep these 4 security “must-dos” in mind. If you have any suggestions or questions, please feel free to contact me or leave a comment in the section below!