Kingdom: Encapsulation
Encapsulation is about drawing strong boundaries. In a web browser that might mean ensuring that your mobile code cannot be abused by other mobile code. On the server it might mean differentiation between validated data and unvalidated data, between one user's data and another's, or between data users are allowed to see and data that they are not.
Insecure Storage: Unspecified Keychain Access Policy
Abstract
The identified method stores data in the Keychain without specifying an accessibility level.
Explanation
When storing data into the Keychain, an accessibility level needs to be set up which defines when it will be possible to access the item. The possible accessibility levels include:
-
The data in the Keychain item cannot be accessed after a restart until the device has been unlocked once by the user.
After the first unlock, the data remains accessible until the next restart. This is recommended for items that need to be accessed by background applications. Items with this attribute do not migrate to a new device. Thus, after restoring from a backup of a different device, these items will not be present.
Available in iOS 4.0 and later.
-
The data in the Keychain item can always be accessed regardless of whether the device is locked.
This is not recommended for application use. Items with this attribute migrate to a new device when using encrypted backups.
Available in iOS 4.0 and later.
-
The data in the Keychain can only be accessed when the device is unlocked. Only available if a passcode is set on the device.
This is recommended for items that only need to be accessible while the application is in the foreground. Items with this attribute never migrate to a new device. After a backup is restored to a new device, these items are missing. No items can be stored in this class on devices without a passcode. Disabling the device passcode causes all items in this class to be deleted.
Available in iOS 8.0 and later.
-
The data in the Keychain item can always be accessed regardless of whether the device is locked.
This is not recommended for application use. Items with this attribute do not migrate to a new device. Thus, after restoring from a backup of a different device, these items will not be present.
Available in iOS 4.0 and later.
-
The data in the Keychain item can be accessed only while the device is unlocked by the user.
This is recommended for items that need to be accessible only while the application is in the foreground. Items with this attribute migrate to a new device when using encrypted backups.
This is the default value for Keychain items added without explicitly setting an accessibility constant.
Available in iOS 4.0 and later.
-
The data in the Keychain item can be accessed only while the device is unlocked by the user.
This is recommended for items that need to be accessible only while the application is in the foreground. Items with this attribute do not migrate to a new device. Thus, after restoring from a backup of a different device, these items will not be present.
Available in iOS 4.0 and later.
When Keychain protections were first introduced, the default value was
Example 1: In the following example the Keychain item is stored without clearly specifying an accessibility level which may behave differently on different iOS versions:
-
kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:The data in the Keychain item cannot be accessed after a restart until the device has been unlocked once by the user.
After the first unlock, the data remains accessible until the next restart. This is recommended for items that need to be accessed by background applications. Items with this attribute do not migrate to a new device. Thus, after restoring from a backup of a different device, these items will not be present.
Available in iOS 4.0 and later.
-
kSecAttrAccessibleAlways
:The data in the Keychain item can always be accessed regardless of whether the device is locked.
This is not recommended for application use. Items with this attribute migrate to a new device when using encrypted backups.
Available in iOS 4.0 and later.
-
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:The data in the Keychain can only be accessed when the device is unlocked. Only available if a passcode is set on the device.
This is recommended for items that only need to be accessible while the application is in the foreground. Items with this attribute never migrate to a new device. After a backup is restored to a new device, these items are missing. No items can be stored in this class on devices without a passcode. Disabling the device passcode causes all items in this class to be deleted.
Available in iOS 8.0 and later.
-
kSecAttrAccessibleAlwaysThisDeviceOnly
:The data in the Keychain item can always be accessed regardless of whether the device is locked.
This is not recommended for application use. Items with this attribute do not migrate to a new device. Thus, after restoring from a backup of a different device, these items will not be present.
Available in iOS 4.0 and later.
-
kSecAttrAccessibleWhenUnlocked
:The data in the Keychain item can be accessed only while the device is unlocked by the user.
This is recommended for items that need to be accessible only while the application is in the foreground. Items with this attribute migrate to a new device when using encrypted backups.
This is the default value for Keychain items added without explicitly setting an accessibility constant.
Available in iOS 4.0 and later.
-
kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:The data in the Keychain item can be accessed only while the device is unlocked by the user.
This is recommended for items that need to be accessible only while the application is in the foreground. Items with this attribute do not migrate to a new device. Thus, after restoring from a backup of a different device, these items will not be present.
Available in iOS 4.0 and later.
When Keychain protections were first introduced, the default value was
kSecAttrAccessibleAlways
, which created a security problem since someone that can get access or steal your device will be able to read the contents of the Keychain. Currently, the default attribute is kSecAttrAccessibleWhenUnlocked
, which is a reasonably restrictive default. However, Apple's public documentation disagrees about what the default attribute is supposed to be, so just in case, you should set this attribute explicitly on all Keychain items.Example 1: In the following example the Keychain item is stored without clearly specifying an accessibility level which may behave differently on different iOS versions:
...
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
NSData *token = [@"secret" dataUsingEncoding:NSUTF8StringEncoding];
// Configure Keychain Item
[dict setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id) kSecClass];
[dict setObject:token forKey:(__bridge id)kSecValueData];
...
OSStatus error = SecItemAdd((__bridge CFDictionaryRef)dict, NULL);
...
References
[1] Keychain Services Apple
[2] Keychain Item Accessibility Constants Apple
[3] David Thiel iOS Application Security: The Definitive Guide for Hackers and Developers No Starch Press
[4] Standards Mapping - Common Weakness Enumeration CWE ID 359
[5] Standards Mapping - Common Weakness Enumeration Top 25 2019 [4] CWE ID 200
[6] Standards Mapping - Common Weakness Enumeration Top 25 2020 [7] CWE ID 200
[7] Standards Mapping - Common Weakness Enumeration Top 25 2021 [20] CWE ID 200
[8] Standards Mapping - Common Weakness Enumeration Top 25 2024 [17] CWE ID 200
[9] Standards Mapping - General Data Protection Regulation (GDPR) Insufficient Data Protection
[10] Standards Mapping - OWASP Application Security Verification Standard 4.0 8.2.2 Client-side Data Protection (L1 L2 L3), 8.3.4 Sensitive Private Data (L1 L2 L3), 10.2.1 Malicious Code Search (L2 L3)
[11] Standards Mapping - OWASP Mobile 2024 M9 Insecure Data Storage
[12] Standards Mapping - OWASP Mobile Application Security Verification Standard 2.0 MASVS-AUTH-2, MASVS-STORAGE-2
[13] Standards Mapping - Payment Card Industry Data Security Standard Version 4.0 Requirement 3.3.1, Requirement 3.5.1, Requirement 4.2.2, Requirement 6.2.4, Requirement 8.3.1
[14] Standards Mapping - Payment Card Industry Data Security Standard Version 4.0.1 Requirement 3.3.1, Requirement 3.3.2, Requirement 3.3.3, Requirement 3.5.1, Requirement 4.2.2, Requirement 6.2.4, Requirement 8.3.1
desc.dataflow.objc.insecure_storage_unspecified_keychain_access_policy
Abstract
The identified method stores data in the Keychain without specifying an accessibility level.
Explanation
When storing data into the Keychain, an accessibility level needs to be set up which defines when it will be possible to access the item. The possible accessibility levels include:
-
The data in the Keychain item cannot be accessed after a restart until the device has been unlocked once by the user.
After the first unlock, the data remains accessible until the next restart. This is recommended for items that need to be accessed by background applications. Items with this attribute do not migrate to a new device. Thus, after restoring from a backup of a different device, these items will not be present.
Available in iOS 4.0 and later.
-
The data in the Keychain item can always be accessed regardless of whether the device is locked.
This is not recommended for application use. Items with this attribute migrate to a new device when using encrypted backups.
Available in iOS 4.0 and later.
-
The data in the Keychain can only be accessed when the device is unlocked. Only available if a passcode is set on the device.
This is recommended for items that only need to be accessible while the application is in the foreground. Items with this attribute never migrate to a new device. After a backup is restored to a new device, these items are missing. No items can be stored in this class on devices without a passcode. Disabling the device passcode causes all items in this class to be deleted.
Available in iOS 8.0 and later.
-
The data in the Keychain item can always be accessed regardless of whether the device is locked.
This is not recommended for application use. Items with this attribute do not migrate to a new device. Thus, after restoring from a backup of a different device, these items will not be present.
Available in iOS 4.0 and later.
-
The data in the Keychain item can be accessed only while the device is unlocked by the user.
This is recommended for items that need to be accessible only while the application is in the foreground. Items with this attribute migrate to a new device when using encrypted backups.
This is the default value for Keychain items added without explicitly setting an accessibility constant.
Available in iOS 4.0 and later.
-
The data in the Keychain item can be accessed only while the device is unlocked by the user.
This is recommended for items that need to be accessible only while the application is in the foreground. Items with this attribute do not migrate to a new device. Thus, after restoring from a backup of a different device, these items will not be present.
Available in iOS 4.0 and later.
When Keychain protections were first introduced, the default value was
Example 1: In the following example the Keychain item is stored without clearly specifying an accessibility level which may behave differently on different iOS versions:
-
kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:The data in the Keychain item cannot be accessed after a restart until the device has been unlocked once by the user.
After the first unlock, the data remains accessible until the next restart. This is recommended for items that need to be accessed by background applications. Items with this attribute do not migrate to a new device. Thus, after restoring from a backup of a different device, these items will not be present.
Available in iOS 4.0 and later.
-
kSecAttrAccessibleAlways
:The data in the Keychain item can always be accessed regardless of whether the device is locked.
This is not recommended for application use. Items with this attribute migrate to a new device when using encrypted backups.
Available in iOS 4.0 and later.
-
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:The data in the Keychain can only be accessed when the device is unlocked. Only available if a passcode is set on the device.
This is recommended for items that only need to be accessible while the application is in the foreground. Items with this attribute never migrate to a new device. After a backup is restored to a new device, these items are missing. No items can be stored in this class on devices without a passcode. Disabling the device passcode causes all items in this class to be deleted.
Available in iOS 8.0 and later.
-
kSecAttrAccessibleAlwaysThisDeviceOnly
:The data in the Keychain item can always be accessed regardless of whether the device is locked.
This is not recommended for application use. Items with this attribute do not migrate to a new device. Thus, after restoring from a backup of a different device, these items will not be present.
Available in iOS 4.0 and later.
-
kSecAttrAccessibleWhenUnlocked
:The data in the Keychain item can be accessed only while the device is unlocked by the user.
This is recommended for items that need to be accessible only while the application is in the foreground. Items with this attribute migrate to a new device when using encrypted backups.
This is the default value for Keychain items added without explicitly setting an accessibility constant.
Available in iOS 4.0 and later.
-
kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:The data in the Keychain item can be accessed only while the device is unlocked by the user.
This is recommended for items that need to be accessible only while the application is in the foreground. Items with this attribute do not migrate to a new device. Thus, after restoring from a backup of a different device, these items will not be present.
Available in iOS 4.0 and later.
When Keychain protections were first introduced, the default value was
kSecAttrAccessibleAlways
, which created a security problem since someone that can get access or steal your device will be able to read the contents of the Keychain. Currently, the default attribute is kSecAttrAccessibleWhenUnlocked
, which is a reasonably restrictive default. However, Apple's public documentation disagrees about what the default attribute is supposed to be, so just in case, you should set this attribute explicitly on all Keychain items.Example 1: In the following example the Keychain item is stored without clearly specifying an accessibility level which may behave differently on different iOS versions:
...
// Configure Keychain Item
let token = "secret"
var query = [String : AnyObject]()
query[kSecClass as String] = kSecClassGenericPassword
query[kSecValueData as String] = token as AnyObject?
SecItemAdd(query as CFDictionary, nil)
...
References
[1] Keychain Services Apple
[2] Keychain Item Accessibility Constants Apple
[3] David Thiel iOS Application Security: The Definitive Guide for Hackers and Developers No Starch Press
[4] Standards Mapping - Common Weakness Enumeration CWE ID 359
[5] Standards Mapping - Common Weakness Enumeration Top 25 2019 [4] CWE ID 200
[6] Standards Mapping - Common Weakness Enumeration Top 25 2020 [7] CWE ID 200
[7] Standards Mapping - Common Weakness Enumeration Top 25 2021 [20] CWE ID 200
[8] Standards Mapping - Common Weakness Enumeration Top 25 2024 [17] CWE ID 200
[9] Standards Mapping - General Data Protection Regulation (GDPR) Insufficient Data Protection
[10] Standards Mapping - OWASP Application Security Verification Standard 4.0 8.2.2 Client-side Data Protection (L1 L2 L3), 8.3.4 Sensitive Private Data (L1 L2 L3), 10.2.1 Malicious Code Search (L2 L3)
[11] Standards Mapping - OWASP Mobile 2024 M9 Insecure Data Storage
[12] Standards Mapping - OWASP Mobile Application Security Verification Standard 2.0 MASVS-AUTH-2, MASVS-STORAGE-2
[13] Standards Mapping - Payment Card Industry Data Security Standard Version 4.0 Requirement 3.3.1, Requirement 3.5.1, Requirement 4.2.2, Requirement 6.2.4, Requirement 8.3.1
[14] Standards Mapping - Payment Card Industry Data Security Standard Version 4.0.1 Requirement 3.3.1, Requirement 3.3.2, Requirement 3.3.3, Requirement 3.5.1, Requirement 4.2.2, Requirement 6.2.4, Requirement 8.3.1
desc.dataflow.swift.insecure_storage_unspecified_keychain_access_policy