Jan 11, 2021, Mobile

Security risks in iOS Development

Patryk Średziński iOS Team Leader

What risks can be discovered in your mobile application?

1. Unsafe environment

Apple’s iOS operating system is considered to be the most secure mobile operating system because of the high Apple’s privacy policy. iOS is not open-source which means that the code of the system is private and known only to Apple’s developers. Although, whenever you’re developing an iOS application, you should keep in mind that in some cases your application data can be leaked out and you can be accused if people find out that their private and secure information has been leaked out while using your application and were published somewhere. That’s why, to stay safe, you should consider doing some safety checks and security updates before releasing your app.

2. Risks and recommendations

Some of the easiest ways that can let a hacker get into your phone and steal your secure data are mentioned in this section. It will show the risks along with the recommendations of how to solve them and drastically increase the chances of a hacker losing interest in cracking your application.

2.1. Jailbreak detection

The most important thing that we need to take care of is a jailbreak. It is a process of removing Apple’s limitations, including all of Apple’s security based core, by injecting a malicious system core. That’s the first step a hacker will do to get into your phone, your sensitive data and your passwords. With a jailbroken phone it is possible to read all the data stored on the device. That’s why you should have a kind of a mechanism that disables your application when it finds out that the device is jailbroken and cleans the data. 

You should also think about people who jailbreak their devices for other reasons. It is forbidden by Apple to jailbreak your device and it vanishes your warranty, but people do it to be able to configure their devices more freely. So, you should make a decision if you want to block them from using your application, or if you’re just going to limit some functionalities. Still, jailbroken devices are less secure.

How to find out if the device is jailbroken? There are some basic and rather small portions of code that with mostly enough probability confirm if the device is jailbroken or not. It is not possible to detect jailbroken device with 100% assurance but you can find some free and public libraries that do the heavy job, like ‘Shadow’ library created by jjolano. If you take a look at the source code, you will see that it does not do anything super unusual, so it can be cheated. But in most cases, it will be just fine. 

2.2. Network communications

Most of the data can be intercepted during all the network calls and there are some simple ways that let the hacker read the communication between your mobile application and the server. They can route all the communications through their local computer and observe them. 

2.2.1. Certificate Pinning

The best and efficient solution to these connectivity risks is to implement certificate pinning. Certificate Pinning can be divided into a couple of more detailed solutions but in general it means that the mobile application is verifying if the server it is connecting to is trusted and their certificate is correct. In other cases it will block out the request. 

For most iOS programmers RayWenderlich is known for a reliable source of truth on iOS development – here you can also read about it.

2.2.2. App Transport Security

You should make sure you’re not allowing requests to a server through HTTP. The server should be put on a secure storage and the communication should be encoded with high quality SSL protocol while you’re connecting through HTTPS. 

You can disable the AppTransportSecurity in your .plist file with NSAllowArbitraryLoads key, but make sure that the value of this key is set to FALSE so all the connections to non secure servers will be blocked out by system.

2.2.3. SSL Protocol

By default, an iOS application does accept weak versions of TLS/SSL protocols which could allow the hacker to intercept your communications. There is a simple solution of how to enable higher versions of more secure protocols. There is a one line change in your URLSession configuration that does fix the issue: 

With .tlsMinimumSupportedProtocol you can control how secure a server has to be in order to communicate with your application. The higher – the better. 

You can also see that it is worth changing the base default configuration to be set to .ephemeral which disables the persistent storage for caches, cookies and credentials. 

2.2.4. Response Cache Leak

In default networking configuration, the network layer does some basic caching of requests and responses on your mobile storage. In most cases it is secured by system, but if the device is jailbroken, it can be easily read and the private data can be leaked out. 

You can make sure that the data is not cached by adding the Cache-Control headers to your server responses so the mobile will handle the response properly. You can use the ‘no-store’ Cache-Control header server side which will be handled properly by mobile and keep the data not stored anywhere.

You can also set another URLSessionConfiguration property to control the way system is storing caches:

2.2.5. Authorization

Make sure you’re using a secure way of handling authorization. You should not keep any of the user’s login or password stored anywhere and sent to the server only once to validate the match. We’d recommend you to use OAuth 2.0 public protocol which will let you exchange your credentials into 2 tokens: access and refresh. Which are used in all other requests making sure you’re not sending any secure information when it is not needed

2.3. Data Storage

A lot of current iOS applications need some kind of local storage. You can use CoreData for large and complex models but sometimes there’s a need to store a very tiny amount of data somewhere. In most cases, UserDefaults are a good solution but you have to be sure that the data stored there has no value to a probable attacker. If you have to store sensitive or secure data, use KeyChain which is much more secure and it is barely impossible to get into these on a non-jailbroken phone, thanks Apple.

You can read more about KeyChains on RayWenderlich’s page.

2.4. Keyboard Extensions

Apple has provided an option to their users to download and install custom keyboards created by other developers. It is highly impossible to create a keyboard extension and put it into AppStore with data-leaking spying code because of Apple’s high review standards but you should think about it: every password you’re typing somewhere in any app on a custom keyboard goes through that keyboard and it could be potentially leaked or published somewhere. It’s not a good idea to login into banks with these keyboards.

There is a simple way to disable all the user’s keyboards in your application and make sure only Apple’s one is working. 

The code above (in AppDelegate) makes sure that your application is not accepting user’s keyboards and it’ll load default one instead.

Remember that your users may not like you for disabling their own and favourite keyboards, so you should decide if you’d like to force them to Apple’s keyboard. 

You can also think about doing your own keyboard only for password (or any secure) fields, but that would require to do much more than adding a few lines to your AppDelegate.

2.5. Logs

Many developers use a very well known command called print all over the code to put important debugging information to the console. Keep in mind that these console logs are stored on your device, and could be read when the device gets a jailbreak. 

Make sure you do print only in DEBUG mode and a RELEASE version is free from prints, or you only print data that does not contain any important information.

2.6. Safe Biometrics

There are many tutorials showing how you can use Biometrics on iPhone 8 and later. People are encouraged to use TouchID and FaceID implementations using the popular LAContext which is fine if you’re not going to deal with secure data in your application. Although, if security is your top priority, you should abandon LAContext implementation and use KeyChain protected with biometrics. 

To protect your KeyChain data with Biometrics, you can create a SecAccessControl with .biometryCurrentSet that will let you read the keychain value only if the user passes the biometrics control. Alexei Gridnev has written a great article about Biometry-protected entries in iOS Keychain.

2.7. Snapshots

The iOS operating system allows multitasking, which means that whenever you leave an application it stays on for a while, and you can go back to it. iOS has a feature that takes a snapshot of the application so it can display the last page the user was on before switching to the second application. It is a great feature but you might want to protect data you’ve displayed. Most banking applications do a great job. They cover the screen with their logo when their application is losing focus, to prevent other users from seeing the balance. 

It can be achieved by observing the applicationDidEnterBackground and applicationDidBecomeActive events and placing/removing an overlay on a window.

3. Summary

Dealing with super secure user private data and passwords should be treated with high security checks. Leaking such data can lead to many unpleasant accusations bringing you in front of the court. Hopefully, Apple does a lot to keep the data private and you’re not needed to that much to increase your app’s security. Focus on jailbreak detection, implement certificate pinning, connect only through safe protocols with trusted remote servers, make sure you’re not storing anything important on the local storage or cache and you should be totally fine.