Skip to main content

Insecure service configuration - App Backup

Need

Secure configuration of application backups

Context

  • Usage of Swift for iOS and macOS app development
  • Usage of UIKit for building modern and responsive user interfaces

Description

Non compliant code

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}

func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
}

func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to store shared data, temporary files, and keep state information.
}

func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state.
}

func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive.
}

func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate.
}

func application(_ application: UIApplication, shouldSaveApplicationState coder: NSCoder) -> Bool {
// This function returns true, which means the state of the application will be saved in case it's terminated.
return true
}

func application(_ application: UIApplication, shouldRestoreApplicationState coder: NSCoder) -> Bool {
// This function returns true, which means the state of the application will be restored if it was previously terminated.
return true
}
}

The code above represents a typical AppDelegate.swift file in an iOS application written in Swift. The AppDelegate.swift file is the core of your app, and it's where your app's state transitions are handled.

The vulnerability lies in the application(_:shouldSaveApplicationState:) and application(_:shouldRestoreApplicationState:) methods. These methods are part of the iOS State Preservation and Restoration process. When these methods return true, it means that the app's state will be saved when it's terminated and restored when it's relaunched. This includes all data in memory at the time of termination.

If an attacker gains access to a user's device, they can access the saved state data and potentially extract sensitive information stored by the app. This is particularly dangerous if your app handles sensitive information such as personal data, credit card numbers, etc.

Steps

  • Disable the backup option for the application.
  • Ensure that sensitive data is not stored locally on the device.
  • Implement secure data storage mechanisms such as encryption or secure keychain storage.
  • Consider using secure cloud storage or server-side storage for sensitive data.
  • Regularly review and update the application's security configurations and practices.

Compliant code

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}

func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
}

func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to store shared data, temporary files, and keep state information.
}

func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state.
}

func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive.
}

func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate.
}

func application(_ application: UIApplication, shouldSaveApplicationState coder: NSCoder) -> Bool {
// This function returns false, which means the state of the application will not be saved in case it's terminated.
return false
}

func application(_ application: UIApplication, shouldRestoreApplicationState coder: NSCoder) -> Bool {
// This function returns false, which means the state of the application will not be restored if it was previously terminated.
return false
}
}

The original code had a vulnerability where the application state was being saved and restored. This could potentially allow an attacker who has access to a user's device to obtain the information stored by the application inside the device.

The fixed code disables the backup option for the application by returning false in the shouldSaveApplicationState and shouldRestoreApplicationState methods. This means that the state of the application will not be saved or restored if the application is terminated.

In addition to this code fix, it is recommended to ensure that sensitive data is not stored locally on the device and to implement secure data storage mechanisms such as encryption or secure keychain storage. Consider using secure cloud storage or server-side storage for sensitive data. Regularly review and update the application's security configurations and practices to prevent potential vulnerabilities.

References