d Dmytro Khludkov  on Engineering October 1, 2020

iOS App Security: 5 Tips to Prevent Sensitive Data Leakage

In a world of increasing data breaches, iOS App security and data protection has become more important than ever. Users are now familiar with how it can be easy to jailbreak iOS device and how some applications grab users’ data. Developers need to be able to easily and efficiently build user data protection into each application to prevent sensitive data leakage upon release and during future updates.

What’s different about iOS app data protection

Unlike Android devices, iOS devices, and accessories are essentially centralized under Apple. And the company takes cybersecurity seriously. From including authentication chips in their accessories to prevent low-quality third-party items and potential malware threats to special enclaves to store sensitive data, such as your ID fingerprints, security is central to the iOS operating system.

Apple’s regulations for iOS app development are no different. Here are five things you should check to ensure you are baking iOS data protection into your application:

1. Sanitize App Screenshots

When an application transitions to the background of an iOS device, the system takes a snapshot of the application’s main window, which it then presents briefly when transitioning your application back to the foreground. This results in potentially sensitive information littering the disk, sometimes even if the user doesn’t intentionally background the app. For example, if someone happens to answer a call in the middle of entering sensitive information into an application, that screen state will be written to disk and remain there until overwritten with another snapshot.

Since this activity can be unintentional for the user, it presents a significant data protection risk.

Once these snapshots are written to disk, a physical attacker can easily retrieve the stored data with common forensics tools. You can even observe the file being written using the Simulator.

So how can you sanitize your user’s screen?

First, the system gives you a few seconds to complete any tasks before applicationDidEnterBackground: method returns. You should use this time to hide or obscure passwords and other sensitive information that might be captured as part of the snapshot. After these tasks are complete, the snapshot should be taken, and the application should disappear with its little “whoosh” animation.

The simplest and most reliable method of obscuring screen content is simply placing a splash screen with a logo or blur effect on top of all the current views. See the sample code below:

class AppDelegate: UIResponder, UIApplicationDelegate {

  var splash: UIImageView?

  /// Add custom splash image before app goes to background
  func applicationDidEnterBackground(_ application: UIApplication) {
    splash = UIImageView(frame: UIScreen.main.bounds)
    splash!.image = UIImage(named: "your-splash-image")
    splash!.isUserInteractionEnabled = false
    UIApplication.shared.keyWindow?.addSubview(splash!)
  }

  /// Remove splash image before App become active
  func applicationWillEnterForeground(_ application: UIApplication) {
    splash?.removeFromSuperview()
    splash = nil
  }
}

Note: if you use a blurring mechanism, make sure it's good enough to prevent unblurring the screen through special software.

Alternatively, you could set the hidden attribute of the relevant screen objects — for example, the UITextFields, which might have sensitive content. You can use the same data protection approach to hide entire UIView objects. This is less visually appealing but easily does the job in a pinch.

2. Setup URLSession Cache Management

Ideally, you won’t ever need to delete the cache with sensitive data because removal means that the data was already cached. The easiest way to fix this is to set cache the capacity to zero, as you can see in the following code snippet:

func applicationDidEnterBackground(_ application: UIApplication) {
  URLCache.shared.diskCapacity = 0
  URLCache.shared.memoryCapacity = 0
}

But there is a problem with this solution - URLCache APIs are not intended for iOS data security. Cache capacity configurations exist to provide the system with information to be used when memory or disk space runs low. The iOS documentation specifies that both the on-disk and in-memory caches will be truncated to the configured sizes only if necessary.

So that code alone will not fully fix the issue in regards to data protection.

The good news is that iOS API provides the ability to manipulate responses before they are cached. In this case, you should implement the URLSessionTaskDelegate function:

Asks the delegate whether the data (or upload) task should store the response in the cache.

func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, willCacheResponse proposedResponse: CachedURLResponse, completionHandler: @escaping (CachedURLResponse?) -> Void) {
  if proposedResponse.response.url?.scheme == "https" {
    /// nil, to prevent caching
    completionHandler(nil)
  } else {
    completionHandler(proposedResponse)
  }
}

If you’re using URLSession, you can also use ephemeral sessions, which will not store any data to disk. This includes information like caches and credentials, which can be ideal for iOS data protection. You just need to use a configuration object for your URLSessions:

let configuration = URLSessionConfiguration.ephemeral

3. Prevent copy-paste sensitive data through the clipboard

Some applications can use users' stored data kept in clipboards. For the sake of data protection, you want to prevent a user from pasting in a card number, password, or any other sensitive data, yet allow the ability to paste other non-sensitive information.

There is a simple way to allow users to paste some information and prevent them from pasting others. In this case you can use the canPerformAction:withSender responder method that can be applied to UITextFields or other UI objects:

extension UITextField {
  open override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
    if action == #selector(UIResponderStandardEditActions.cut) || action ==  #selector(UIResponderStandardEditActions.copy) {
      return false
    }
    return super.canPerformAction(action, withSender: sender)
   }
}

4. Disable autocomplete for fields with sensitive data

The autocomplete mechanism works as a collection of keywords, recording the text that a user types in text inputs UI objects to improve keyboard corrections and proactive integration with other text input opportunities. Because of this, autocomplete becomes a gap in data protection. An attacker can easily retrieve that completion database and get a hold of a user’s sensitive data.

Autocompletion can be an even bigger headache when it’s used in wrong use cases, such as being enabled on shared iOS devices with the same logged-in account, such as terminals in stores.

The good news it’s easy to disable autocomplete for fields that collect sensitive data and offer your app users more data protection:

textField.autocorrectionType = .no

This behavior is disabled by default for UITextField objects with isSecureTextEntry = true set.

5. Use secure text fields

As you already read before, secure text fields not only hide the sensitive data from potential snoops, but they also prevent the iOS device from collecting input from the autocomplete mechanism.

And secure fields can do more - they hide the input data on screenshots and video recorded on views with secure fields. It’s an essential component of any data protection strategy.

This behavior is disabled by default. To enable secure text entry you just need to set isSecureTextEntry:

textField.isSecureTextEntry = true

Data protection for your iOS app made easy

As we can see from these five examples, securing your iOS app doesn’t have to be a time-consuming process. In fact, in most cases, only a few lines of code will suffice. We would also recommend that you review your application's security and take a look at every 3rd-party framework within it to ensure that your data protection methods are still working as intended. Make sure that your framework and integrations don't send any strange requests with sensitive data outside the application, take screenshots of application views, or use analytics to log the sensitive data.

Learn more about VGS.

Subscribe to our Blog

Please enter a valid email address.