This product is not supported for your selected Datadog site. ().
Cette page n'est pas encore disponible en français, sa traduction est en cours.
Si vous avez des questions ou des retours sur notre projet de traduction actuel, n'hésitez pas à nous contacter.

Metadata

ID: swift-security/exportable-keychain

Language: Unknown

Severity: Notice

Category: Security

Description

This rule aims to prevent the export of sensitive data by ensuring secure keychain accessibility settings in Swift applications. Exporting sensitive data with improper keychain access attributes, such as kSecAttrAccessibleAlways or kSecAttrAccessibleAfterFirstUnlock, increases the risk of unauthorized access, especially if the device is compromised or stolen.

To comply with this rule, always set the kSecAttrAccessible attribute to a secure value that limits data accessibility to the device only and requires user authentication or passcode protection. For example, use query[kSecAttrAccessible as String] = kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly instead of less secure options. This practice minimizes the risk of sensitive data leakage from your app’s keychain storage.

Non-Compliant Code Examples

class keychainController: keychainViewController {
    func foo(_ data: Data, forKey key: String) {
        let query: [NSString: Any] = [
            kSecClass: secClass,
            kSecAttrAccount: key,
            kSecAttrAccessGroup: accessGroup
        ]
        let attributes: [NSString: Any] = [
            kSecValueData: data,
            kSecAttrAccessible: kSecAttrAccessibleAfterFirstUnlock
        ] 
    }  
    
}
class keychainController: keychainViewController {
    func foo() {
        let keychainItemQuery = [
            kSecValueData: "test123".data(using: .utf8)!,
            kSecClass: kSecClassGenericPassword,
            kSecAttrAccessible: kSecAttrAccessibleAfterFirstUnlock
        ] as CFDictionary
        SecItemAdd(keychainItemQuery, nil)
    }
}
class keychainController: keychainViewController {
    func foo() {
        var query: [String: Any] = [kSecClass as String: kSecClassInternetPassword,
                                    kSecAttrAccount as String: account,
                                    kSecAttrServer as String: server,
                                    kSecValueData as String: password,
                                    kSecAttrAccessible as String: kSecAttrAccessibleAlways]
        SecItemAdd(query,r)
    }
}
class keychainController: keychainViewController {
    func foo() {
        var query = [String : AnyObject]()
        query[kSecAttrAccessible as String] = kSecAttrAccessibleAlways
        SecItemAdd(query as CFDictionary, nil)
    }
}
class keychainController: keychainViewController {
    func foo() {
        var query = [String : AnyObject]()
        query[kSecAttrAccessible as String] = kSecAttrAccessibleAlways
        SecItemAdd(query as CFDictionary, nil)
    }
    
    
}
class keychainController: keychainViewController {
    func foo() {
        var query = [String : AnyObject]()
        query[kSecAttrAccessible as String] = kSecAttrAccessibleAfterFirstUnlock
        SecItemAdd(query as CFDictionary, nil)
    }
}

Compliant Code Examples

class keychainController: keychainViewController {

    func foo(_ data: Data, forKey key: String) {
        let query: [NSString: Any] = [
            kSecClass: secClass,
            kSecAttrAccount: key,
            kSecAttrAccessGroup: accessGroup
        ]
        let attributes: [NSString: Any] = [
            kSecValueData: data,
            kSecAttrAccessible: kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
        ] 
    } 
}
class keychainController: keychainViewController {
    func foo() {
        var query = [String : AnyObject]()
        query[kSecAttrAccessible as String] = kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
        SecItemAdd(query as CFDictionary, nil)
    }  
}
https://static.datadoghq.com/static/images/logos/github_avatar.svg https://static.datadoghq.com/static/images/logos/vscode_avatar.svg jetbrains