1. UITextField safety: disable autocomplete

iOS takes values from UITextField fields and stores them in clear text on the file system as part of autocomplete functionality. There are 2 common approaches for preventing this behavior, which may vary depending on your use case.

  • Use the secureTextEntry attribute: This attribute marks the text field so it’s contents are not displayed back to the user. This is useful for fields such as passwords.
  • Disable autocomplete: Whenever possible, autocomplete should be disabled for sensitive fields. Use the  UITextAutocorrectionTypeno attribute to disable autocomplete.
  • Avoid using NSUserDefaults to store sensitive pieces of information
  • Disable copy/paste option for sensitive field like username, password. Reference link

 

  1. Storing secrets with ‘Keychain Services’

Small amounts of consumer grade sensitive data, such as user authentication credentials, session tokens, etc., can be securely stored in the device’s Keychain

Objective C Reference link

Swift Reference link

 

  1. Excluding files from iCloud backups

Certain files may contain sensitive information and you may not want them backed up into Apple’s iCloud. In this case, set the NSURLIsExcludedFromBackupKey attribute using setResourceValue:forKey:error to instruct iOS 5.1 and above not to include the file within a backup.

Reference Link

 

  1. Dropping NSLOG in release build

    We commonly use NSLog for debugging purposes. These logs might include requests, responses, cookies, authentication tokens and other sensitive data. On the iPhone, Apple System Log (ASL) logs data passed to the NSLog function and the data remains on the log until the device is rebooted. Also, Error logs are not bounded by the application sandbox. Which means error logs generated by one application can be read by other applications. Therefore, if an application logs sensitive data, a malicious application can actively query for this data and send it to a remote server.As a solution to this, you can use Dlog or ALog instead of NSLog command. Add the following to the <AppName>_Prefix.pch file in your Xcode project

     #ifdef  
        #define DLog(...) NSLog(__VA_ARGS__)  
     #else  
        # define DLog(...) /* */  
     #endif  
     #define ALog(...) NSLog(__VA_ARGS__)  
    

    Reference link

     

  2. Check for sensitive information in snapshots

    In order to provide the visual transitions in the interface, iOS has been proven to capture and store snapshots (screenshots or captures) as images stored in the file system portion of the device NAND flash. This occurs when an application suspends (rather than terminates), when either the home button is pressed, or a phone call or other event temporarily suspends the application. These images can often contain user and application’s sensitive data.This will cause big concern to Banking or eCommerce apps; When User is checking banking details, transaction data or personal information. Example: There is My Account Info screen, which is displaying user sensitive data.

    Security.docx

       (snapshot before implementation)

    To protect data from taking the snapshot, we can hide value fields in applicationDidEnterBackground: method.

    Objective C

     - (void)applicationDidEnterBackground:(UIApplication *)application {  
          viewController.accountNumberField.hidden = YES;  
          viewController.balanceField.hidden = YES;  
          viewController.dobField.hidden = YES;  
          viewController.maidenNameField.hidden = YES;  
          viewController.secretQuestionField.hidden = YES;  
          viewController.secretAnswerField.hidden = YES;   
     //OR  
          UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.window.bounds];  
          imageView.tag = 101;  
          [imageView setBackgroundColor:[UIColor blueColor]];    
          [UIApplication.sharedApplication.keyWindow.subviews.lastObject addSubview:imageView];  
     }  
    

    Swift

     func applicationDidEnterBackground(_ application: UIApplication) {
            viewController.accountNumberField.isHidden = true
            viewController.balanceField.isHidden = true
            viewController.dobField.isHidden = true
            viewController.maidenNameField.isHidden = true
            viewController.secretQuestionField.isHidden = true
            viewController.secretAnswerField.isHidden = true
            //OR
            let imageView =  UIImageView(frame: (self.window?.bounds)!)
            imageView.tag = 101;
            imageView.backgroundColor = UIColor.blue
            UIApplication.shared.keyWindow?.subviews.last?.addSubview(imageView)
        }
    

    You also need to make the fields visible before the app becomes active using the following code in applicationDidBecomeActive:

    Objectice C

     - (void)applicationDidBecomeActive:(UIApplication *)application {  
          viewController.accountNumberField.hidden = NO;  
          viewController.balanceField.hidden = NO;  
          viewController.dobField.hidden = NO;  
          viewController.maidenNameField.hidden = NO;  
          viewController.secretQuestionField.hidden = NO;  
          viewController.secretAnswerField.hidden = NO;  
     //OR  
          UIImageView *imageView = (UIImageView *) [UIApplication.sharedApplication.keyWindow.subviews.lastObject viewWithTag:101  
          [imageView removeFromSuperview];  
     }  
    

    Swift

     func applicationWillResignActive(_ application: UIApplication) {
            viewController.accountNumberField.isHidden = false
            viewController.balanceField.isHidden = false
            viewController.dobField.isHidden = false
            viewController.maidenNameField.isHidden = false
            viewController.secretQuestionField.isHidden = false
            viewController.secretAnswerField.isHidden = false
            //OR
            if let imageView = UIApplication.shared.keyWindow?.subviews.last?.viewWithTag(101) as? UIImageView {
                imageView.removeFromSuperview()
            }
      }
    

    Adding this code to the delegate results in the following screen shot (without sensitive data) being taken when the home button is pressed.

    Untitled

         (snapshot after implementation)
  3. Insecure database

For Banking and eCommerce apps, we commonly use SQLite as local database storage. We store user sensitive data in it but its not secure way. Locally stored data (document directory) can be easily extracted using simple hacking technique.

To protect SQLite, We can store it in a encrypted format. Here SQLICipher is best solution. SQLCipher is a specialized build of the excellent SQLite db that performs transparent and on-the-fly encryption. Using SQLCipher, an application uses the standard SQLite API to manipulate tables using SQL. Behind the scenes the library silently manages the security aspects, making sure that data pages are encrypted and decrypted as they are written to and read from storage.

Reference Link