Currently, security is one of the hottest topics in IT. Users, companies, and legislators are taking the subject of data security and privacy more and more seriously. This trend also applies to mobile applications due to their proximity to the user. Frequency of use and convenience mean that mobile apps often store important private data. iOS, due to its closed system and restrictions imposed by Apple, is considered one of the most secure mobile operating systems. This does not mean, however, that you can neglect security when developing an iOS application.
iOS Security is a very wide topic that is hard to present in one article, but we can easily identify the basic threats:
User data leak. By using the application, the user usually enters their private data. Storing data in an unsecured manner creates the risk of this data being leaked if the device falls into unauthorised hands.
Man in the middle attack. Intercepting http(s) requests and responses is relatively easy to do when it comes to iOS apps. Unfortunately, SSL is not enough to make your app secure. Using tools like Charles Proxy, even an amateur can get to know our app requests, corresponding server responses, and manipulate network traffic by sending doctored requests.
Reverse engineering. Thanks to reverse engineering, the attacker can obtain the URL addresses, identifiers, keys that you use in the application, understand business its logic, or steal your intellectual property - especially if you employ sophisticated algorithms. What's more, (s)he can also modify the behaviour of the application and, for example, omit the login screen.
How to make your app secure
User data protection
In order to protect user data, focus on two aspects - using the right solutions for data storage, and securing data as it’s entered. Logins, keys, and passwords should be stored in Keychain. Keychain is the password management system developed by Apple, distributed both with macOS and iOS. The iOS version is simpler, and sharing Keychain items between different apps in is not possible on iOS. This means that iOS Keychain items are only accessible to the app that created them.
You can however, use other tools to store other user data which are not so critical. It is worth mentioning two solutions - Core Data and Realm Database.
Core Data is Apple’s persistence framework with an underlying SQLite database. This means that developers interface with Core Data methods, not the database directly, and is insulated from what happens under the hood. What is important is that, by default, SQLite is not encrypted when the app is unlocked. Apple has a feature called "Data Protection" which encrypts the sandbox if the device is locked with a passcode. But we cannot always rely on the end user to passcode protect his/her device. The device can be jailbroken, passcodes can be easy to crack, or be written down on the phone’s protective case by unaware users. Not everyone is tech-savvy. If encryption by passcode is not sufficient, we need to use a third-party solution like the Encrypted Core Data SQLite Store which allows us to encrypt SQLite even while the device is unlocked.
Another solution is the Realm Database, an open source alternative to SQLite and Core Data. It allows you to encrypt data very easily using strong AES-256 encryption. Data are encrypted even when the device is unlocked, and your encryption key can be stored securely in the system Keychain. This means that only your app can decrypt these data. Realm seems to be a really good solution in terms of security.
Another area for protecting data is user input. We need to be aware that the keyboards used in iOS cause data to be cached for auto-correction. Auto-correction should be turned off for fields used for sensitive user data input. A similar case exists for screenshots. When an app goes to background, the system takes a screenshot. If users input sensitive data and it is visible on screen, we need to implement a mechanism for masking the screen before the app goes to background.
Protecting from reverse engineering
In the case of reverse engineering, unfortunately, we can do very little. One option is to develop your application in Swift. Swift is a much newer language than Objective-C, so the reverse engineering tools are not as well developed. You should also use secure ways of storing application keys for specific environments - for example by using Cocoapods Keys. The last option is to use obfuscation, misleading method names, creating traps and fake methods for an attacker. The problem is that this approach makes code harder to maintain, slower to develop, and much more prone to errors. In most cases, the costs of such a solution will outweigh the benefits.
In case of manipulating network traffic and man in the middle attacks, SSL pinning should be implemented. SSL pinning is a method used to ensure that an application communicates only with the right server. The SSL certificate is saved within the app bundle and is used when defining the pinned certificate upon session configuration.
Last, but not least, it is definitely worth doing a security audit before launching an app. It doesn’t always mean spending a fortune hiring an external team of hackers. Sometimes going through OWASP Mobile Application Security Verification Standard could be enough. The MASVS is a security checklist for mobile applications published by a leading not-for-profit organisation focused on improving software security. Although the document is not iOS-specific, it is definitely worth going through before releasing an app.
iOS is relatively secure compared to other mobile operating systems. Apple provides great security mechanisms like Keychain, data encryption by passcode, or App Transport Security, which forces developers to use SSL. However, it doesn’t mean that these solutions are sufficient in every case. Making an app secure is not rocket science - it’s all about using the proper solutions and spending a little time before release.