Secure storage of administrative credentials
import UIKit
class LoginViewController: UIViewController {
@IBOutlet weak var usernameField: UITextField!
@IBOutlet weak var passwordField: UITextField!
@IBAction func loginButtonTapped(_ sender: Any) {
let username = usernameField.text!
let password = passwordField.text!
UserDefaults.standard.setValue(username, forKey: "username")
UserDefaults.standard.setValue(password, forKey: "password")
}
}
The above Swift code represents a simple login screen in an iOS application where a user can enter their username and password. When the login button is tapped, the entered username and password are stored in the UserDefaults which is a simple, easy-to-use interface to the user’s default system.
The vulnerability here is that the administrative credentials (username and password) are being stored in UserDefaults. UserDefaults are not encrypted and can be accessed by anyone who has access to the device. This allows for potential attackers to easily retrieve these credentials from the device's cache memory.
Storing sensitive information like usernames and passwords directly into UserDefaults is a bad practice because UserDefaults are not meant for storing sensitive information. They are meant for storing small amounts of data that doesn't need to be secure. Also, UserDefaults are stored in plist files which are easily readable.
This code should be fixed by removing the storage of the username and password from UserDefaults and instead using a secure method for storing these credentials, such as Keychain Services.
import UIKit
import Security
class LoginViewController: UIViewController {
@IBOutlet weak var usernameField: UITextField!
@IBOutlet weak var passwordField: UITextField!
@IBAction func loginButtonTapped(_ sender: Any) {
let username = usernameField.text!
let password = passwordField.text!
// Store credentials securely in Keychain
let keychainQuery: [NSString: Any] = [
kSecClass: kSecClassGenericPassword,
kSecAttrAccount: username,
kSecValueData: password.data(using: .utf8)!
]
let status = SecItemAdd(keychainQuery as CFDictionary, nil)
guard status == errSecSuccess else { return }
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
// Clear text fields
usernameField.text = ""
passwordField.text = ""
}
}
The updated code now securely stores the administrative credentials in the Keychain instead of UserDefaults. Keychain is a secure storage mechanism provided by iOS that is designed to keep sensitive data, like user credentials, secure.
In the
loginButtonTapped
function, we create a dictionary
keychainQuery
that contains the class of the item we want to add to the Keychain (
kSecClassGenericPassword
), the account name (
username
), and the password (
password
). We then call
SecItemAdd
to add this new item to the Keychain. If the function returns
errSecSuccess
, the item was successfully added.
In the
viewDidDisappear
function, we clear the text fields. This ensures that the sensitive information is cleared from memory after it is no longer needed.
This code does not implement access controls to restrict access to the sensitive information. This would need to be implemented at a higher level, such as requiring the user to authenticate before accessing the view that contains the
LoginViewController
.