계: Encapsulation

캡슐화는 강력한 경계를 그리는 것입니다. 웹 브라우저에서는 사용자의 모바일 코드가 다른 모바일 코드에 의해 오용되지 않도록 하는 것을 의미합니다. 서버에서는 검증된 데이터와 검증되지 않은 데이터, 한 사용자의 데이터와 다른 사용자의 데이터, 데이터 사용자가 볼 수 있는 데이터와 볼 수 없는 데이터 간의 차별화를 의미할 수 있습니다.

Insecure Storage: Unspecified Keychain Access Policy

Abstract
식별된 메서드는 액세스 가능성 수준을 지정하지 않고 키 집합에 데이터를 저장합니다.
Explanation
키 집합에 데이터를 저장할 때는 항목에 액세스가 가능한 경우를 정의하는 액세스 가능성 수준을 설정해야 합니다. 가능한 액세스 가능성 수준에는 다음이 포함됩니다.

-kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly:
재시작 후 사용자가 장치를 한 번 잠금 해제하기 전까지는 키 집합 항목의 데이터에 액세스할 수 없습니다.
처음 잠금 해제 후에는 다음 재시작까지 계속 액세스 가능한 상태로 유지됩니다. 백그라운드 응용 프로그램이 액세스해야 하는 항목에 권장합니다. 이 특성이 지정된 항목은 새 장치로 마이그레이션되지 않습니다. 따라서 다른 장치의 백업에서 복원된 후에는 이러한 항목이 존재하지 않습니다.
iOS 4.0 이상에서 사용 가능합니다.

-kSecAttrAccessibleAlways:
장치가 잠겼는지 여부에 관계 없이 키 집합 항목의 데이터에 언제나 액세스할 수 있습니다.
응용 프로그램 사용에 권장하지 않습니다. 이 특성이 지정된 항목은 암호화된 백업을 사용할 때 새 장치로 마이그레이션됩니다.
iOS 4.0 이상에서 사용 가능합니다.

-kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly:
장치가 잠금 해제되었을 때만 키 집합의 데이터에 액세스할 수 있습니다. 장치에 암호가 설정된 경우에만 사용할 수 있습니다.
응용 프로그램이 전경에 있을 때만 액세스할 수 있어야 하는 항목에 권장합니다. 이 특성이 지정된 항목은 새 장치로 마이그레이션되지 않습니다. 백업이 새 장치로 복원된 후에는 이러한 항목이 없어집니다. 암호가 없는 장치에서는 이 클래스에 항목을 저장할 수 없습니다. 장치 암호를 비활성화하면 이 클래스의 모든 항목이 삭제됩니다.
iOS 8.0 이상에서 사용 가능합니다.

-kSecAttrAccessibleAlwaysThisDeviceOnly:
장치가 잠겼는지 여부에 관계 없이 키 집합 항목의 데이터에 언제나 액세스할 수 있습니다.
응용 프로그램 사용에 권장하지 않습니다. 이 특성이 지정된 항목은 새 장치로 마이그레이션되지 않습니다. 따라서 다른 장치의 백업에서 복원된 후에는 이러한 항목이 존재하지 않습니다.
iOS 4.0 이상에서 사용 가능합니다.

-kSecAttrAccessibleWhenUnlocked:
사용자가 장치를 잠금 해제하고 있을 때만 키 집합 항목의 데이터에 액세스할 수 있습니다.
응용 프로그램이 전경에 있을 때만 액세스할 수 있어야 하는 항목에 권장합니다. 이 특성이 지정된 항목은 암호화된 백업을 사용할 때 새 장치로 마이그레이션됩니다.
액세스 가능성 상수를 명시적으로 설정하지 않고 추가된 키 집합 항목에 대한 기본값입니다.
iOS 4.0 이상에서 사용 가능합니다.

-kSecAttrAccessibleWhenUnlockedThisDeviceOnly:
사용자가 장치를 잠금 해제하고 있을 때만 키 집합 항목의 데이터에 액세스할 수 있습니다.
응용 프로그램이 전경에 있을 때만 액세스할 수 있어야 하는 항목에 권장합니다. 이 특성이 지정된 항목은 새 장치로 마이그레이션되지 않습니다. 따라서 다른 장치의 백업에서 복원된 후에는 이러한 항목이 존재하지 않습니다.
iOS 4.0 이상에서 사용 가능합니다.

키 집합 보호 기능이 처음 도입되었을 때 기본값은 kSecAttrAccessibleAlways였습니다. 그런데 장치를 훔치거나 액세스를 획득한 누군가가 키 집합의 내용을 읽을 수 있기 때문에 이 기본값에는 보안 문제가 있었습니다. 현재의 기본 특성은 적절하게 엄격한 기본값인 kSecAttrAccessibleWhenUnlocked입니다. 하지만 Apple의 공개 설명서에서는 무엇을 기본 특성으로 사용해야 하는지에 대해 의견이 다르기 때문에 만약에 대비하여 모든 키 집합 항목에서 이 특성을 명시적으로 설정해야 합니다.

예제 1: 다음 예제에서는 액세스 가능성 수준을 명확하게 지정하지 않고 키 집합 항목이 저장되어 iOS 버전에 따라 다르게 동작할 수 있습니다.


...
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 - CIS Azure Kubernetes Service Benchmark 2
[5] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 4
[6] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 3
[7] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
[8] Standards Mapping - Common Weakness Enumeration CWE ID 359
[9] Standards Mapping - Common Weakness Enumeration Top 25 2019 [4] CWE ID 200
[10] Standards Mapping - Common Weakness Enumeration Top 25 2020 [7] CWE ID 200
[11] Standards Mapping - Common Weakness Enumeration Top 25 2021 [20] CWE ID 200
[12] Standards Mapping - General Data Protection Regulation (GDPR) Insufficient Data Protection
[13] 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)
[14] Standards Mapping - OWASP Mobile 2024 M9 Insecure Data Storage
[15] Standards Mapping - OWASP Mobile Application Security Verification Standard 2.0 MASVS-AUTH-2, MASVS-STORAGE-2
[16] 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
desc.dataflow.objc.insecure_storage_unspecified_keychain_access_policy
Abstract
식별된 메서드는 액세스 가능성 수준을 지정하지 않고 키 집합에 데이터를 저장합니다.
Explanation
키 집합에 데이터를 저장할 때는 항목에 액세스가 가능한 경우를 정의하는 액세스 가능성 수준을 설정해야 합니다. 가능한 액세스 가능성 수준에는 다음이 포함됩니다.

-kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly:
재시작 후 사용자가 장치를 한 번 잠금 해제하기 전까지는 키 집합 항목의 데이터에 액세스할 수 없습니다.
처음 잠금 해제 후에는 다음 재시작까지 계속 액세스 가능한 상태로 유지됩니다. 백그라운드 응용 프로그램이 액세스해야 하는 항목에 권장합니다. 이 특성이 지정된 항목은 새 장치로 마이그레이션되지 않습니다. 따라서 다른 장치의 백업에서 복원된 후에는 이러한 항목이 존재하지 않습니다.
iOS 4.0 이상에서 사용 가능합니다.

-kSecAttrAccessibleAlways:
장치가 잠겼는지 여부에 관계 없이 키 집합 항목의 데이터에 언제나 액세스할 수 있습니다.
응용 프로그램 사용에 권장하지 않습니다. 이 특성이 지정된 항목은 암호화된 백업을 사용할 때 새 장치로 마이그레이션됩니다.
iOS 4.0 이상에서 사용 가능합니다.

-kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly:
장치가 잠금 해제되었을 때만 키 집합의 데이터에 액세스할 수 있습니다. 장치에 암호가 설정된 경우에만 사용할 수 있습니다.
응용 프로그램이 전경에 있을 때만 액세스할 수 있어야 하는 항목에 권장합니다. 이 특성이 지정된 항목은 새 장치로 마이그레이션되지 않습니다. 백업이 새 장치로 복원된 후에는 이러한 항목이 없어집니다. 암호가 없는 장치에서는 이 클래스에 항목을 저장할 수 없습니다. 장치 암호를 비활성화하면 이 클래스의 모든 항목이 삭제됩니다.
iOS 8.0 이상에서 사용 가능합니다.

-kSecAttrAccessibleAlwaysThisDeviceOnly:
장치가 잠겼는지 여부에 관계 없이 키 집합 항목의 데이터에 언제나 액세스할 수 있습니다.
응용 프로그램 사용에 권장하지 않습니다. 이 특성이 지정된 항목은 새 장치로 마이그레이션되지 않습니다. 따라서 다른 장치의 백업에서 복원된 후에는 이러한 항목이 존재하지 않습니다.
iOS 4.0 이상에서 사용 가능합니다.

-kSecAttrAccessibleWhenUnlocked:
사용자가 장치를 잠금 해제하고 있을 때만 키 집합 항목의 데이터에 액세스할 수 있습니다.
응용 프로그램이 전경에 있을 때만 액세스할 수 있어야 하는 항목에 권장합니다. 이 특성이 지정된 항목은 암호화된 백업을 사용할 때 새 장치로 마이그레이션됩니다.
액세스 가능성 상수를 명시적으로 설정하지 않고 추가된 키 집합 항목에 대한 기본값입니다.
iOS 4.0 이상에서 사용 가능합니다.

-kSecAttrAccessibleWhenUnlockedThisDeviceOnly:
사용자가 장치를 잠금 해제하고 있을 때만 키 집합 항목의 데이터에 액세스할 수 있습니다.
응용 프로그램이 전경에 있을 때만 액세스할 수 있어야 하는 항목에 권장합니다. 이 특성이 지정된 항목은 새 장치로 마이그레이션되지 않습니다. 따라서 다른 장치의 백업에서 복원된 후에는 이러한 항목이 존재하지 않습니다.
iOS 4.0 이상에서 사용 가능합니다.

키 집합 보호 기능이 처음 도입되었을 때 기본값은 kSecAttrAccessibleAlways였습니다. 그런데 장치를 훔치거나 액세스를 획득한 누군가가 키 집합의 내용을 읽을 수 있기 때문에 이 기본값에는 보안 문제가 있었습니다. 현재의 기본 특성은 적절하게 엄격한 기본값인 kSecAttrAccessibleWhenUnlocked입니다. 하지만 Apple의 공개 설명서에서는 무엇을 기본 특성으로 사용해야 하는지에 대해 의견이 다르기 때문에 만약에 대비하여 모든 키 집합 항목에서 이 특성을 명시적으로 설정해야 합니다.

예제 1: 다음 예제에서는 액세스 가능성 수준을 명확하게 지정하지 않고 키 집합 항목이 저장되어 iOS 버전에 따라 다르게 동작할 수 있습니다.


...
// 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 - CIS Azure Kubernetes Service Benchmark 2
[5] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 4
[6] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 3
[7] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
[8] Standards Mapping - Common Weakness Enumeration CWE ID 359
[9] Standards Mapping - Common Weakness Enumeration Top 25 2019 [4] CWE ID 200
[10] Standards Mapping - Common Weakness Enumeration Top 25 2020 [7] CWE ID 200
[11] Standards Mapping - Common Weakness Enumeration Top 25 2021 [20] CWE ID 200
[12] Standards Mapping - General Data Protection Regulation (GDPR) Insufficient Data Protection
[13] 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)
[14] Standards Mapping - OWASP Mobile 2024 M9 Insecure Data Storage
[15] Standards Mapping - OWASP Mobile Application Security Verification Standard 2.0 MASVS-AUTH-2, MASVS-STORAGE-2
[16] 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
desc.dataflow.swift.insecure_storage_unspecified_keychain_access_policy