Non-encrypted confidential information - Swift

Non-encrypted confidential information - Swift

Need

Secure storage of confidential information

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

class ViewController: UIViewController {

    @IBOutlet weak var usernameField: UITextField!
    @IBOutlet weak var passwordField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    @IBAction func loginButtonTapped(_ sender: Any) {
        let username = usernameField.text!
        let password = passwordField.text!
        
        // Storing the username and password in UserDefaults
        let defaults = UserDefaults.standard
        defaults.set(username, forKey: "username")
        defaults.set(password, forKey: "password")
    }
}
        
        

This Swift code is a simple view controller for a login screen. The user enters their username and password into the text fields, and when the login button is tapped, the entered username and password are stored in UserDefaults.

The main vulnerability lies in the loginButtonTapped(_:) function. Here, the user's confidential information (username and password) is stored directly in UserDefaults without any encryption. UserDefaults is not a secure place to store sensitive information as it's stored in plain text. This means anyone with access to the file system can easily retrieve this information. If an attacker were to gain access to the device, they could easily extract these plain text credentials and misuse them.

The code is vulnerable as it does not employ any form of encryption or secure storage to protect the user's confidential information. It's a violation of best practices for secure coding and puts user data at significant risk.

Steps

  • Use a secure storage mechanism to store confidential information instead of UserDefaults.
  • Encrypt the confidential information before storing it.
  • Use secure communication protocols (e.g., HTTPS) when transmitting the confidential information over the network.
  • Implement proper access controls to restrict unauthorized access to the confidential information.
  • Regularly update and patch the application to address any security vulnerabilities.

Compliant code

        import UIKit
import Security

class ViewController: UIViewController {

    @IBOutlet weak var usernameField: UITextField!
    @IBOutlet weak var passwordField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    @IBAction func loginButtonTapped(_ sender: Any) {
        let username = usernameField.text!
        let password = passwordField.text!
        
        // Encrypt and store the username and password securely
        let usernameData = Data(username.utf8)
        let passwordData = Data(password.utf8)
        
        let statusUsername = KeychainWrapper.standard.set(usernameData, forKey: "username")
        let statusPassword = KeychainWrapper.standard.set(passwordData, forKey: "password")
        
        if statusUsername && statusPassword {
            print("Values saved in Keychain")
        } else {
            print("Failed to save in Keychain")
        }
    }
}
        
        

The above code fixes the vulnerability by encrypting the confidential information (username and password) and storing it securely using the Keychain, which is a secure storage mechanism provided by iOS.

The KeychainWrapper.standard.set function is used to store the encrypted data in the Keychain. This function returns a boolean value indicating whether the operation was successful or not. If both the username and password are successfully stored in the Keychain, a message "Values saved in Keychain" is printed to the console. Otherwise, a message "Failed to save in Keychain" is printed.

This approach ensures that even if an attacker gains access to the device, they will not be able to retrieve the confidential information without the encryption key. Furthermore, the Keychain is protected by iOS's built-in security features, making it a much safer option for storing confidential information compared to UserDefaults.

Please note that you need to import the Security framework and use a Keychain wrapper library (like SwiftKeychainWrapper) to use the Keychain in Swift.

References