Description
The kSecAttrAccessibleAlways family permits access to Keychain items while the device is locked, increasing exposure risks if a device is lost, jailbroken, or restored from a backup.
Potential impact
- Access to Keychain items while the device is locked
- Sensitive data exposure following device loss or backup restoration
- Reuse of stolen tokens or passwords
Remediation
- Prefer
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnlyfor sensitive items. - If background access is required, select a more restrictive option such as
AfterFirstUnlockThisDeviceOnly. - Use device-only accessibility where possible to prevent migration through backups.
Examples
Before
swift
query[kSecAttrAccessible as String] = kSecAttrAccessibleAlways
After
swift
import Foundation
import Security
enum KeychainStorageError: Error {
case unexpectedStatus(OSStatus)
}
func saveToken(_ token: Data) throws {
let item: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: "com.example.app.auth",
kSecAttrAccount as String: "access_token",
kSecAttrAccessible as String:
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
kSecValueData as String: token
]
let addStatus = SecItemAdd(item as CFDictionary, nil)
if addStatus == errSecSuccess { return }
guard addStatus == errSecDuplicateItem else {
throw KeychainStorageError.unexpectedStatus(addStatus)
}
let match: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: "com.example.app.auth",
kSecAttrAccount as String: "access_token"
]
let updates: [String: Any] = [
kSecAttrAccessible as String:
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
kSecValueData as String: token
]
let updateStatus = SecItemUpdate(
match as CFDictionary, updates as CFDictionary)
guard updateStatus == errSecSuccess else {
throw KeychainStorageError.unexpectedStatus(updateStatus)
}
}
Explanation:
- Before: Item access is permitted regardless of the device's lock state.
- After: The code requires passcode and device-only protection and checks Keychain operation results. Existing items are updated with the same strong accessibility setting. Failures, including a missing device passcode, do not trigger a fallback to weaker accessibility.