From d66e407c3e5ad2632e946c6f73d3ac7edb3362ca Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 29 Jul 2024 17:02:57 +0100 Subject: [PATCH 1/6] Swift: Improve the encryption in examples for swift/cleartext-* queries. --- .../Security/CWE-311/CleartextStorageDatabase.swift | 10 ++++++++-- .../Security/CWE-311/CleartextTransmission.swift | 10 ++++++++-- .../Security/CWE-312/CleartextStoragePreferences.swift | 10 ++++++++-- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.swift b/swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.swift index bf4ec78527c4..eabcbb7eac22 100644 --- a/swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.swift +++ b/swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.swift @@ -1,5 +1,11 @@ +import CryptoKit -func storeMyData(databaseObject : NSManagedObject, faveSong : String, creditCardNo : String) { +private func encrypt(_ text: String, _ encryptionKey: SymmetricKey) -> String { + let sealedBox = try! AES.GCM.seal(Data(text.utf8), using: encryptionKey) + return sealedBox.combined!.base64EncodedString() +} + +func storeMyData(databaseObject : NSManagedObject, faveSong : String, creditCardNo : String, key: SymmetricKey) { // ... // GOOD: not sensitive information @@ -9,7 +15,7 @@ func storeMyData(databaseObject : NSManagedObject, faveSong : String, creditCard databaseObject.setValue(creditCardNo, forKey: "myCreditCardNo") // GOOD: encrypted sensitive information saved - databaseObject.setValue(encrypt(creditCardNo), forKey: "myCreditCardNo") + databaseObject.setValue(encrypt(creditCardNo, encryptionKey), forKey: "myCreditCardNo") // ... } diff --git a/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.swift b/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.swift index 7a0f9f1e8ddb..62dda307935a 100644 --- a/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.swift +++ b/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.swift @@ -1,5 +1,11 @@ +import CryptoKit -func transmitMyData(connection : NWConnection, faveSong : String, creditCardNo : String) { +private func encrypt(_ text: String, _ encryptionKey: SymmetricKey) -> String { + let sealedBox = try! AES.GCM.seal(Data(text.utf8), using: encryptionKey) + return sealedBox.combined!.base64EncodedString() +} + +func transmitMyData(connection : NWConnection, faveSong : String, creditCardNo : String, key: SymmetricKey) { // ... // GOOD: not sensitive information @@ -9,7 +15,7 @@ func transmitMyData(connection : NWConnection, faveSong : String, creditCardNo : connection.send(content: creditCardNo, completion: .idempotent) // GOOD: encrypted sensitive information saved - connection.send(content: encrypt(creditCardNo), completion: .idempotent) + connection.send(content: encrypt(creditCardNo, encryptionKey), completion: .idempotent) // ... } diff --git a/swift/ql/src/queries/Security/CWE-312/CleartextStoragePreferences.swift b/swift/ql/src/queries/Security/CWE-312/CleartextStoragePreferences.swift index 98df511802b9..9b1fdf870cdf 100644 --- a/swift/ql/src/queries/Security/CWE-312/CleartextStoragePreferences.swift +++ b/swift/ql/src/queries/Security/CWE-312/CleartextStoragePreferences.swift @@ -1,5 +1,11 @@ +import CryptoKit -func storeMyData(faveSong : String, creditCardNo : String) { +private func encrypt(_ text: String, _ encryptionKey: SymmetricKey) -> String { + let sealedBox = try! AES.GCM.seal(Data(text.utf8), using: encryptionKey) + return sealedBox.combined!.base64EncodedString() +} + +func storeMyData(faveSong : String, creditCardNo : String, encryptionKey: SymmetricKey) { // ... // GOOD: not sensitive information @@ -9,7 +15,7 @@ func storeMyData(faveSong : String, creditCardNo : String) { UserDefaults.standard.set(creditCardNo, forKey: "myCreditCardNo") // GOOD: encrypted sensitive information saved - UserDefaults.standard.set(encrypt(creditCardNo), forKey: "myCreditCardNo") + UserDefaults.standard.set(encrypt(creditCardNo, encryptionKey), forKey: "myCreditCardNo") // ... } From 41c3d1b83352c1a21b44c805f7f1bee3e37ee7db Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 29 Jul 2024 17:23:14 +0100 Subject: [PATCH 2/6] Swift: Mention key management in the .qhelp + add a reference about key management. --- .../queries/Security/CWE-311/CleartextStorageDatabase.qhelp | 6 +++++- .../queries/Security/CWE-311/CleartextTransmission.qhelp | 6 +++++- .../Security/CWE-312/CleartextStoragePreferences.qhelp | 6 +++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.qhelp b/swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.qhelp index 3571499c9cfe..b66885dc3692 100644 --- a/swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.qhelp +++ b/swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.qhelp @@ -12,7 +12,7 @@ -

The following example shows three cases of storing information using the Core Data library. In the 'BAD' case, the data that is stored is sensitive (a credit card number) and is not encrypted. In the 'GOOD' cases, the data is either not sensitive, or is protected with encryption.

+

The following example shows three cases of storing information using the Core Data library. In the 'BAD' case, the data that is stored is sensitive (a credit card number) and is not encrypted. In the 'GOOD' cases, the data is either not sensitive, or is protected with encryption. When encryption is used, care must be taken to select a secure modern encryption algorithm and put suitable key management practices into place.

@@ -23,6 +23,10 @@ OWASP Top 10:2021: A02:2021 � Cryptographic Failures. +
  • + OWASP: + Key Management Cheat Sheet. +
  • diff --git a/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.qhelp b/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.qhelp index 8cce5caa74eb..2008072403ab 100644 --- a/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.qhelp +++ b/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.qhelp @@ -12,7 +12,7 @@ -

    The following example shows three cases of transmitting information. In the 'BAD' case, the data transmitted is sensitive (a credit card number) and is not encrypted. In the 'GOOD' cases, the data is either not sensitive, or is protected with encryption.

    +

    The following example shows three cases of transmitting information. In the 'BAD' case, the data transmitted is sensitive (a credit card number) and is not encrypted. In the 'GOOD' cases, the data is either not sensitive, or is protected with encryption. When encryption is used, care must be taken to select a secure modern encryption algorithm and put suitable key management practices into place.

    @@ -23,6 +23,10 @@ OWASP Top 10:2021: A02:2021 � Cryptographic Failures. +
  • + OWASP: + Key Management Cheat Sheet. +
  • diff --git a/swift/ql/src/queries/Security/CWE-312/CleartextStoragePreferences.qhelp b/swift/ql/src/queries/Security/CWE-312/CleartextStoragePreferences.qhelp index 89f473c74c9d..da3c9d9a32f7 100644 --- a/swift/ql/src/queries/Security/CWE-312/CleartextStoragePreferences.qhelp +++ b/swift/ql/src/queries/Security/CWE-312/CleartextStoragePreferences.qhelp @@ -12,7 +12,7 @@ -

    The following example shows three cases of storing information using UserDefaults. In the 'BAD' case, the data that is stored is sensitive (a credit card number) and is not encrypted. In the 'GOOD' cases, the data is either not sensitive, or is protected with encryption.

    +

    The following example shows three cases of storing information using UserDefaults. In the 'BAD' case, the data that is stored is sensitive (a credit card number) and is not encrypted. In the 'GOOD' cases, the data is either not sensitive, or is protected with encryption. When encryption is used, care must be taken to select a secure modern encryption algorithm and put suitable key management practices into place.

    @@ -26,6 +26,10 @@
  • Apple Developer Documentation: UserDefaults, NSUbiquitousKeyValueStore
  • +
  • + OWASP: + Key Management Cheat Sheet. +
  • From 3d6a889d2414c84a6c8d76d9065d1af463c1f3f8 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 30 Jul 2024 16:48:42 +0100 Subject: [PATCH 3/6] Swift: Make use of CBC blockmode in examples and tests mode accurate. --- .../CWE-321/HardcodedEncryptionKey.swift | 8 +- .../Security/CWE-327/ECBEncryption.swift | 9 +- .../CWE-321/HardcodedEncryptionKey.expected | 146 +++++++++--------- .../Security/CWE-321/cryptoswift.swift | 10 +- .../Security/CWE-327/ECBEncryption.expected | 52 +++---- .../query-tests/Security/CWE-327/test.swift | 22 ++- 6 files changed, 128 insertions(+), 119 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-321/HardcodedEncryptionKey.swift b/swift/ql/src/queries/Security/CWE-321/HardcodedEncryptionKey.swift index dcc273b77716..f6dba4d9cdac 100644 --- a/swift/ql/src/queries/Security/CWE-321/HardcodedEncryptionKey.swift +++ b/swift/ql/src/queries/Security/CWE-321/HardcodedEncryptionKey.swift @@ -6,9 +6,9 @@ func encrypt(padding : Padding) { let key: Array = [0x2a, 0x3a, 0x80, 0x05] let keyString = "this is a constant string" let ivString = getRandomIV() - _ = try AES(key: key, blockMode: CBC(), padding: padding) + _ = try AES(key: key, blockMode: CBC(AES.randomIV(AES.blockSize)), padding: padding) _ = try AES(key: keyString, iv: ivString) - _ = try Blowfish(key: key, blockMode: CBC(), padding: padding) + _ = try Blowfish(key: key, blockMode: CBC(Blowfish.randomIV(Blowfish.blockSize)), padding: padding) _ = try Blowfish(key: keyString, iv: ivString) @@ -18,9 +18,9 @@ func encrypt(padding : Padding) { if status == errSecSuccess { let keyString = String(cString: key) let ivString = getRandomIV() - _ = try AES(key: key, blockMode: CBC(), padding: padding) + _ = try AES(key: key, blockMode: CBC(AES.randomIV(AES.blockSize)), padding: padding) _ = try AES(key: keyString, iv: ivString) - _ = try Blowfish(key: key, blockMode: CBC(), padding: padding) + _ = try Blowfish(key: key, blockMode: CBC(Blowfish.randomIV(Blowfish.blockSize)), padding: padding) _ = try Blowfish(key: keyString, iv: ivString) } diff --git a/swift/ql/src/queries/Security/CWE-327/ECBEncryption.swift b/swift/ql/src/queries/Security/CWE-327/ECBEncryption.swift index 1f45c4a28936..429d185698fb 100644 --- a/swift/ql/src/queries/Security/CWE-327/ECBEncryption.swift +++ b/swift/ql/src/queries/Security/CWE-327/ECBEncryption.swift @@ -9,10 +9,11 @@ func encrypt(key : Key, padding : Padding) { _ = try Blowfish(key: key, blockMode: blockMode, padding: padding) // GOOD: ECB is not used for block mode - let blockMode = CBC() - _ = try AES(key: key, blockMode: blockMode, padding: padding) - _ = try AES(key: key, blockMode: blockMode) - _ = try Blowfish(key: key, blockMode: blockMode, padding: padding) + let aesBlockMode = CBC(iv: AES.randomIV(AES.blockSize)) + let blowfishBlockMode = CBC(iv: Blowfish.randomIV(Blowfish.blockSize)) + _ = try AES(key: key, blockMode: aesBlockMode, padding: padding) + _ = try AES(key: key, blockMode: aesBlockMode) + _ = try Blowfish(key: key, blockMode: blowfishBlockMode, padding: padding) // ... } diff --git a/swift/ql/test/query-tests/Security/CWE-321/HardcodedEncryptionKey.expected b/swift/ql/test/query-tests/Security/CWE-321/HardcodedEncryptionKey.expected index 9a671de00578..19dfd75b9841 100644 --- a/swift/ql/test/query-tests/Security/CWE-321/HardcodedEncryptionKey.expected +++ b/swift/ql/test/query-tests/Security/CWE-321/HardcodedEncryptionKey.expected @@ -1,31 +1,31 @@ edges | SQLite.swift:54:25:54:33 | [...] | SQLite.swift:54:13:54:34 | call to Blob.init(bytes:) | provenance | | -| cryptoswift.swift:76:3:76:3 | this string is constant | cryptoswift.swift:80:10:80:28 | call to getConstantString() | provenance | | -| cryptoswift.swift:76:3:76:3 | this string is constant | cryptoswift.swift:92:18:92:36 | call to getConstantString() | provenance | | -| cryptoswift.swift:80:2:80:34 | call to Array.init(_:) [Collection element] | cryptoswift.swift:91:13:91:30 | call to getConstantArray() [Collection element] | provenance | | -| cryptoswift.swift:80:10:80:28 | call to getConstantString() | cryptoswift.swift:80:10:80:30 | .utf8 | provenance | | -| cryptoswift.swift:80:10:80:30 | .utf8 | cryptoswift.swift:80:2:80:34 | call to Array.init(_:) [Collection element] | provenance | | -| cryptoswift.swift:90:26:90:121 | [...] | cryptoswift.swift:117:22:117:22 | key | provenance | | -| cryptoswift.swift:90:26:90:121 | [...] | cryptoswift.swift:118:22:118:22 | key | provenance | | -| cryptoswift.swift:90:26:90:121 | [...] | cryptoswift.swift:128:26:128:26 | key | provenance | | -| cryptoswift.swift:90:26:90:121 | [...] | cryptoswift.swift:135:25:135:25 | key | provenance | | -| cryptoswift.swift:90:26:90:121 | [...] | cryptoswift.swift:140:25:140:25 | key | provenance | | -| cryptoswift.swift:90:26:90:121 | [...] | cryptoswift.swift:145:26:145:26 | key | provenance | | -| cryptoswift.swift:90:26:90:121 | [...] | cryptoswift.swift:150:26:150:26 | key | provenance | | -| cryptoswift.swift:90:26:90:121 | [...] | cryptoswift.swift:151:26:151:26 | key | provenance | | -| cryptoswift.swift:90:26:90:121 | [...] | cryptoswift.swift:161:24:161:24 | key | provenance | | -| cryptoswift.swift:90:26:90:121 | [...] | cryptoswift.swift:163:24:163:24 | key | provenance | | -| cryptoswift.swift:91:13:91:30 | call to getConstantArray() [Collection element] | cryptoswift.swift:106:21:106:21 | key2 | provenance | | -| cryptoswift.swift:91:13:91:30 | call to getConstantArray() [Collection element] | cryptoswift.swift:107:21:107:21 | key2 | provenance | | -| cryptoswift.swift:92:18:92:36 | call to getConstantString() | cryptoswift.swift:108:21:108:21 | keyString | provenance | | -| cryptoswift.swift:92:18:92:36 | call to getConstantString() | cryptoswift.swift:109:21:109:21 | keyString | provenance | | -| cryptoswift.swift:92:18:92:36 | call to getConstantString() | cryptoswift.swift:119:22:119:22 | keyString | provenance | | -| cryptoswift.swift:92:18:92:36 | call to getConstantString() | cryptoswift.swift:120:22:120:22 | keyString | provenance | | -| cryptoswift.swift:92:18:92:36 | call to getConstantString() | cryptoswift.swift:129:26:129:26 | keyString | provenance | | -| cryptoswift.swift:92:18:92:36 | call to getConstantString() | cryptoswift.swift:152:26:152:26 | keyString | provenance | | -| cryptoswift.swift:92:18:92:36 | call to getConstantString() | cryptoswift.swift:153:26:153:26 | keyString | provenance | | -| cryptoswift.swift:92:18:92:36 | call to getConstantString() | cryptoswift.swift:162:24:162:24 | keyString | provenance | | -| cryptoswift.swift:92:18:92:36 | call to getConstantString() | cryptoswift.swift:164:24:164:24 | keyString | provenance | | +| cryptoswift.swift:78:2:78:2 | this string is constant | cryptoswift.swift:82:10:82:28 | call to getConstantString() | provenance | | +| cryptoswift.swift:78:2:78:2 | this string is constant | cryptoswift.swift:94:18:94:36 | call to getConstantString() | provenance | | +| cryptoswift.swift:82:2:82:34 | call to Array.init(_:) [Collection element] | cryptoswift.swift:93:13:93:30 | call to getConstantArray() [Collection element] | provenance | | +| cryptoswift.swift:82:10:82:28 | call to getConstantString() | cryptoswift.swift:82:10:82:30 | .utf8 | provenance | | +| cryptoswift.swift:82:10:82:30 | .utf8 | cryptoswift.swift:82:2:82:34 | call to Array.init(_:) [Collection element] | provenance | | +| cryptoswift.swift:92:26:92:121 | [...] | cryptoswift.swift:119:22:119:22 | key | provenance | | +| cryptoswift.swift:92:26:92:121 | [...] | cryptoswift.swift:120:22:120:22 | key | provenance | | +| cryptoswift.swift:92:26:92:121 | [...] | cryptoswift.swift:130:26:130:26 | key | provenance | | +| cryptoswift.swift:92:26:92:121 | [...] | cryptoswift.swift:137:25:137:25 | key | provenance | | +| cryptoswift.swift:92:26:92:121 | [...] | cryptoswift.swift:142:25:142:25 | key | provenance | | +| cryptoswift.swift:92:26:92:121 | [...] | cryptoswift.swift:147:26:147:26 | key | provenance | | +| cryptoswift.swift:92:26:92:121 | [...] | cryptoswift.swift:152:26:152:26 | key | provenance | | +| cryptoswift.swift:92:26:92:121 | [...] | cryptoswift.swift:153:26:153:26 | key | provenance | | +| cryptoswift.swift:92:26:92:121 | [...] | cryptoswift.swift:163:24:163:24 | key | provenance | | +| cryptoswift.swift:92:26:92:121 | [...] | cryptoswift.swift:165:24:165:24 | key | provenance | | +| cryptoswift.swift:93:13:93:30 | call to getConstantArray() [Collection element] | cryptoswift.swift:108:21:108:21 | key2 | provenance | | +| cryptoswift.swift:93:13:93:30 | call to getConstantArray() [Collection element] | cryptoswift.swift:109:21:109:21 | key2 | provenance | | +| cryptoswift.swift:94:18:94:36 | call to getConstantString() | cryptoswift.swift:110:21:110:21 | keyString | provenance | | +| cryptoswift.swift:94:18:94:36 | call to getConstantString() | cryptoswift.swift:111:21:111:21 | keyString | provenance | | +| cryptoswift.swift:94:18:94:36 | call to getConstantString() | cryptoswift.swift:121:22:121:22 | keyString | provenance | | +| cryptoswift.swift:94:18:94:36 | call to getConstantString() | cryptoswift.swift:122:22:122:22 | keyString | provenance | | +| cryptoswift.swift:94:18:94:36 | call to getConstantString() | cryptoswift.swift:131:26:131:26 | keyString | provenance | | +| cryptoswift.swift:94:18:94:36 | call to getConstantString() | cryptoswift.swift:154:26:154:26 | keyString | provenance | | +| cryptoswift.swift:94:18:94:36 | call to getConstantString() | cryptoswift.swift:155:26:155:26 | keyString | provenance | | +| cryptoswift.swift:94:18:94:36 | call to getConstantString() | cryptoswift.swift:164:24:164:24 | keyString | provenance | | +| cryptoswift.swift:94:18:94:36 | call to getConstantString() | cryptoswift.swift:166:24:166:24 | keyString | provenance | | | file://:0:0:0:0 | [post] self | misc.swift:30:7:30:7 | self [Return] | provenance | | | file://:0:0:0:0 | [post] self [encryptionKey] | file://:0:0:0:0 | [post] self | provenance | | | file://:0:0:0:0 | [post] self [encryptionKey] | file://:0:0:0:0 | [post] self | provenance | | @@ -79,34 +79,34 @@ nodes | SQLite.swift:49:79:49:79 | hardcoded_key | semmle.label | hardcoded_key | | SQLite.swift:54:13:54:34 | call to Blob.init(bytes:) | semmle.label | call to Blob.init(bytes:) | | SQLite.swift:54:25:54:33 | [...] | semmle.label | [...] | -| cryptoswift.swift:76:3:76:3 | this string is constant | semmle.label | this string is constant | -| cryptoswift.swift:80:2:80:34 | call to Array.init(_:) [Collection element] | semmle.label | call to Array.init(_:) [Collection element] | -| cryptoswift.swift:80:10:80:28 | call to getConstantString() | semmle.label | call to getConstantString() | -| cryptoswift.swift:80:10:80:30 | .utf8 | semmle.label | .utf8 | -| cryptoswift.swift:90:26:90:121 | [...] | semmle.label | [...] | -| cryptoswift.swift:91:13:91:30 | call to getConstantArray() [Collection element] | semmle.label | call to getConstantArray() [Collection element] | -| cryptoswift.swift:92:18:92:36 | call to getConstantString() | semmle.label | call to getConstantString() | -| cryptoswift.swift:106:21:106:21 | key2 | semmle.label | key2 | -| cryptoswift.swift:107:21:107:21 | key2 | semmle.label | key2 | -| cryptoswift.swift:108:21:108:21 | keyString | semmle.label | keyString | -| cryptoswift.swift:109:21:109:21 | keyString | semmle.label | keyString | -| cryptoswift.swift:117:22:117:22 | key | semmle.label | key | -| cryptoswift.swift:118:22:118:22 | key | semmle.label | key | -| cryptoswift.swift:119:22:119:22 | keyString | semmle.label | keyString | -| cryptoswift.swift:120:22:120:22 | keyString | semmle.label | keyString | -| cryptoswift.swift:128:26:128:26 | key | semmle.label | key | -| cryptoswift.swift:129:26:129:26 | keyString | semmle.label | keyString | -| cryptoswift.swift:135:25:135:25 | key | semmle.label | key | -| cryptoswift.swift:140:25:140:25 | key | semmle.label | key | -| cryptoswift.swift:145:26:145:26 | key | semmle.label | key | -| cryptoswift.swift:150:26:150:26 | key | semmle.label | key | -| cryptoswift.swift:151:26:151:26 | key | semmle.label | key | -| cryptoswift.swift:152:26:152:26 | keyString | semmle.label | keyString | -| cryptoswift.swift:153:26:153:26 | keyString | semmle.label | keyString | -| cryptoswift.swift:161:24:161:24 | key | semmle.label | key | -| cryptoswift.swift:162:24:162:24 | keyString | semmle.label | keyString | +| cryptoswift.swift:78:2:78:2 | this string is constant | semmle.label | this string is constant | +| cryptoswift.swift:82:2:82:34 | call to Array.init(_:) [Collection element] | semmle.label | call to Array.init(_:) [Collection element] | +| cryptoswift.swift:82:10:82:28 | call to getConstantString() | semmle.label | call to getConstantString() | +| cryptoswift.swift:82:10:82:30 | .utf8 | semmle.label | .utf8 | +| cryptoswift.swift:92:26:92:121 | [...] | semmle.label | [...] | +| cryptoswift.swift:93:13:93:30 | call to getConstantArray() [Collection element] | semmle.label | call to getConstantArray() [Collection element] | +| cryptoswift.swift:94:18:94:36 | call to getConstantString() | semmle.label | call to getConstantString() | +| cryptoswift.swift:108:21:108:21 | key2 | semmle.label | key2 | +| cryptoswift.swift:109:21:109:21 | key2 | semmle.label | key2 | +| cryptoswift.swift:110:21:110:21 | keyString | semmle.label | keyString | +| cryptoswift.swift:111:21:111:21 | keyString | semmle.label | keyString | +| cryptoswift.swift:119:22:119:22 | key | semmle.label | key | +| cryptoswift.swift:120:22:120:22 | key | semmle.label | key | +| cryptoswift.swift:121:22:121:22 | keyString | semmle.label | keyString | +| cryptoswift.swift:122:22:122:22 | keyString | semmle.label | keyString | +| cryptoswift.swift:130:26:130:26 | key | semmle.label | key | +| cryptoswift.swift:131:26:131:26 | keyString | semmle.label | keyString | +| cryptoswift.swift:137:25:137:25 | key | semmle.label | key | +| cryptoswift.swift:142:25:142:25 | key | semmle.label | key | +| cryptoswift.swift:147:26:147:26 | key | semmle.label | key | +| cryptoswift.swift:152:26:152:26 | key | semmle.label | key | +| cryptoswift.swift:153:26:153:26 | key | semmle.label | key | +| cryptoswift.swift:154:26:154:26 | keyString | semmle.label | keyString | +| cryptoswift.swift:155:26:155:26 | keyString | semmle.label | keyString | | cryptoswift.swift:163:24:163:24 | key | semmle.label | key | | cryptoswift.swift:164:24:164:24 | keyString | semmle.label | keyString | +| cryptoswift.swift:165:24:165:24 | key | semmle.label | key | +| cryptoswift.swift:166:24:166:24 | keyString | semmle.label | keyString | | file://:0:0:0:0 | [post] self | semmle.label | [post] self | | file://:0:0:0:0 | [post] self | semmle.label | [post] self | | file://:0:0:0:0 | [post] self [encryptionKey] | semmle.label | [post] self [encryptionKey] | @@ -165,27 +165,27 @@ subpaths | SQLite.swift:47:15:47:15 | hardcoded_key | SQLite.swift:47:15:47:15 | hardcoded_key | SQLite.swift:47:15:47:15 | hardcoded_key | The key 'hardcoded_key' has been initialized with hard-coded values from $@. | SQLite.swift:47:15:47:15 | hardcoded_key | hardcoded_key | | SQLite.swift:49:79:49:79 | hardcoded_key | SQLite.swift:49:79:49:79 | hardcoded_key | SQLite.swift:49:79:49:79 | hardcoded_key | The key 'hardcoded_key' has been initialized with hard-coded values from $@. | SQLite.swift:49:79:49:79 | hardcoded_key | hardcoded_key | | SQLite.swift:54:13:54:34 | call to Blob.init(bytes:) | SQLite.swift:54:25:54:33 | [...] | SQLite.swift:54:13:54:34 | call to Blob.init(bytes:) | The key 'call to Blob.init(bytes:)' has been initialized with hard-coded values from $@. | SQLite.swift:54:25:54:33 | [...] | [...] | -| cryptoswift.swift:106:21:106:21 | key2 | cryptoswift.swift:76:3:76:3 | this string is constant | cryptoswift.swift:106:21:106:21 | key2 | The key 'key2' has been initialized with hard-coded values from $@. | cryptoswift.swift:76:3:76:3 | this string is constant | this string is constant | -| cryptoswift.swift:107:21:107:21 | key2 | cryptoswift.swift:76:3:76:3 | this string is constant | cryptoswift.swift:107:21:107:21 | key2 | The key 'key2' has been initialized with hard-coded values from $@. | cryptoswift.swift:76:3:76:3 | this string is constant | this string is constant | -| cryptoswift.swift:108:21:108:21 | keyString | cryptoswift.swift:76:3:76:3 | this string is constant | cryptoswift.swift:108:21:108:21 | keyString | The key 'keyString' has been initialized with hard-coded values from $@. | cryptoswift.swift:76:3:76:3 | this string is constant | this string is constant | -| cryptoswift.swift:109:21:109:21 | keyString | cryptoswift.swift:76:3:76:3 | this string is constant | cryptoswift.swift:109:21:109:21 | keyString | The key 'keyString' has been initialized with hard-coded values from $@. | cryptoswift.swift:76:3:76:3 | this string is constant | this string is constant | -| cryptoswift.swift:117:22:117:22 | key | cryptoswift.swift:90:26:90:121 | [...] | cryptoswift.swift:117:22:117:22 | key | The key 'key' has been initialized with hard-coded values from $@. | cryptoswift.swift:90:26:90:121 | [...] | [...] | -| cryptoswift.swift:118:22:118:22 | key | cryptoswift.swift:90:26:90:121 | [...] | cryptoswift.swift:118:22:118:22 | key | The key 'key' has been initialized with hard-coded values from $@. | cryptoswift.swift:90:26:90:121 | [...] | [...] | -| cryptoswift.swift:119:22:119:22 | keyString | cryptoswift.swift:76:3:76:3 | this string is constant | cryptoswift.swift:119:22:119:22 | keyString | The key 'keyString' has been initialized with hard-coded values from $@. | cryptoswift.swift:76:3:76:3 | this string is constant | this string is constant | -| cryptoswift.swift:120:22:120:22 | keyString | cryptoswift.swift:76:3:76:3 | this string is constant | cryptoswift.swift:120:22:120:22 | keyString | The key 'keyString' has been initialized with hard-coded values from $@. | cryptoswift.swift:76:3:76:3 | this string is constant | this string is constant | -| cryptoswift.swift:128:26:128:26 | key | cryptoswift.swift:90:26:90:121 | [...] | cryptoswift.swift:128:26:128:26 | key | The key 'key' has been initialized with hard-coded values from $@. | cryptoswift.swift:90:26:90:121 | [...] | [...] | -| cryptoswift.swift:129:26:129:26 | keyString | cryptoswift.swift:76:3:76:3 | this string is constant | cryptoswift.swift:129:26:129:26 | keyString | The key 'keyString' has been initialized with hard-coded values from $@. | cryptoswift.swift:76:3:76:3 | this string is constant | this string is constant | -| cryptoswift.swift:135:25:135:25 | key | cryptoswift.swift:90:26:90:121 | [...] | cryptoswift.swift:135:25:135:25 | key | The key 'key' has been initialized with hard-coded values from $@. | cryptoswift.swift:90:26:90:121 | [...] | [...] | -| cryptoswift.swift:140:25:140:25 | key | cryptoswift.swift:90:26:90:121 | [...] | cryptoswift.swift:140:25:140:25 | key | The key 'key' has been initialized with hard-coded values from $@. | cryptoswift.swift:90:26:90:121 | [...] | [...] | -| cryptoswift.swift:145:26:145:26 | key | cryptoswift.swift:90:26:90:121 | [...] | cryptoswift.swift:145:26:145:26 | key | The key 'key' has been initialized with hard-coded values from $@. | cryptoswift.swift:90:26:90:121 | [...] | [...] | -| cryptoswift.swift:150:26:150:26 | key | cryptoswift.swift:90:26:90:121 | [...] | cryptoswift.swift:150:26:150:26 | key | The key 'key' has been initialized with hard-coded values from $@. | cryptoswift.swift:90:26:90:121 | [...] | [...] | -| cryptoswift.swift:151:26:151:26 | key | cryptoswift.swift:90:26:90:121 | [...] | cryptoswift.swift:151:26:151:26 | key | The key 'key' has been initialized with hard-coded values from $@. | cryptoswift.swift:90:26:90:121 | [...] | [...] | -| cryptoswift.swift:152:26:152:26 | keyString | cryptoswift.swift:76:3:76:3 | this string is constant | cryptoswift.swift:152:26:152:26 | keyString | The key 'keyString' has been initialized with hard-coded values from $@. | cryptoswift.swift:76:3:76:3 | this string is constant | this string is constant | -| cryptoswift.swift:153:26:153:26 | keyString | cryptoswift.swift:76:3:76:3 | this string is constant | cryptoswift.swift:153:26:153:26 | keyString | The key 'keyString' has been initialized with hard-coded values from $@. | cryptoswift.swift:76:3:76:3 | this string is constant | this string is constant | -| cryptoswift.swift:161:24:161:24 | key | cryptoswift.swift:90:26:90:121 | [...] | cryptoswift.swift:161:24:161:24 | key | The key 'key' has been initialized with hard-coded values from $@. | cryptoswift.swift:90:26:90:121 | [...] | [...] | -| cryptoswift.swift:162:24:162:24 | keyString | cryptoswift.swift:76:3:76:3 | this string is constant | cryptoswift.swift:162:24:162:24 | keyString | The key 'keyString' has been initialized with hard-coded values from $@. | cryptoswift.swift:76:3:76:3 | this string is constant | this string is constant | -| cryptoswift.swift:163:24:163:24 | key | cryptoswift.swift:90:26:90:121 | [...] | cryptoswift.swift:163:24:163:24 | key | The key 'key' has been initialized with hard-coded values from $@. | cryptoswift.swift:90:26:90:121 | [...] | [...] | -| cryptoswift.swift:164:24:164:24 | keyString | cryptoswift.swift:76:3:76:3 | this string is constant | cryptoswift.swift:164:24:164:24 | keyString | The key 'keyString' has been initialized with hard-coded values from $@. | cryptoswift.swift:76:3:76:3 | this string is constant | this string is constant | +| cryptoswift.swift:108:21:108:21 | key2 | cryptoswift.swift:78:2:78:2 | this string is constant | cryptoswift.swift:108:21:108:21 | key2 | The key 'key2' has been initialized with hard-coded values from $@. | cryptoswift.swift:78:2:78:2 | this string is constant | this string is constant | +| cryptoswift.swift:109:21:109:21 | key2 | cryptoswift.swift:78:2:78:2 | this string is constant | cryptoswift.swift:109:21:109:21 | key2 | The key 'key2' has been initialized with hard-coded values from $@. | cryptoswift.swift:78:2:78:2 | this string is constant | this string is constant | +| cryptoswift.swift:110:21:110:21 | keyString | cryptoswift.swift:78:2:78:2 | this string is constant | cryptoswift.swift:110:21:110:21 | keyString | The key 'keyString' has been initialized with hard-coded values from $@. | cryptoswift.swift:78:2:78:2 | this string is constant | this string is constant | +| cryptoswift.swift:111:21:111:21 | keyString | cryptoswift.swift:78:2:78:2 | this string is constant | cryptoswift.swift:111:21:111:21 | keyString | The key 'keyString' has been initialized with hard-coded values from $@. | cryptoswift.swift:78:2:78:2 | this string is constant | this string is constant | +| cryptoswift.swift:119:22:119:22 | key | cryptoswift.swift:92:26:92:121 | [...] | cryptoswift.swift:119:22:119:22 | key | The key 'key' has been initialized with hard-coded values from $@. | cryptoswift.swift:92:26:92:121 | [...] | [...] | +| cryptoswift.swift:120:22:120:22 | key | cryptoswift.swift:92:26:92:121 | [...] | cryptoswift.swift:120:22:120:22 | key | The key 'key' has been initialized with hard-coded values from $@. | cryptoswift.swift:92:26:92:121 | [...] | [...] | +| cryptoswift.swift:121:22:121:22 | keyString | cryptoswift.swift:78:2:78:2 | this string is constant | cryptoswift.swift:121:22:121:22 | keyString | The key 'keyString' has been initialized with hard-coded values from $@. | cryptoswift.swift:78:2:78:2 | this string is constant | this string is constant | +| cryptoswift.swift:122:22:122:22 | keyString | cryptoswift.swift:78:2:78:2 | this string is constant | cryptoswift.swift:122:22:122:22 | keyString | The key 'keyString' has been initialized with hard-coded values from $@. | cryptoswift.swift:78:2:78:2 | this string is constant | this string is constant | +| cryptoswift.swift:130:26:130:26 | key | cryptoswift.swift:92:26:92:121 | [...] | cryptoswift.swift:130:26:130:26 | key | The key 'key' has been initialized with hard-coded values from $@. | cryptoswift.swift:92:26:92:121 | [...] | [...] | +| cryptoswift.swift:131:26:131:26 | keyString | cryptoswift.swift:78:2:78:2 | this string is constant | cryptoswift.swift:131:26:131:26 | keyString | The key 'keyString' has been initialized with hard-coded values from $@. | cryptoswift.swift:78:2:78:2 | this string is constant | this string is constant | +| cryptoswift.swift:137:25:137:25 | key | cryptoswift.swift:92:26:92:121 | [...] | cryptoswift.swift:137:25:137:25 | key | The key 'key' has been initialized with hard-coded values from $@. | cryptoswift.swift:92:26:92:121 | [...] | [...] | +| cryptoswift.swift:142:25:142:25 | key | cryptoswift.swift:92:26:92:121 | [...] | cryptoswift.swift:142:25:142:25 | key | The key 'key' has been initialized with hard-coded values from $@. | cryptoswift.swift:92:26:92:121 | [...] | [...] | +| cryptoswift.swift:147:26:147:26 | key | cryptoswift.swift:92:26:92:121 | [...] | cryptoswift.swift:147:26:147:26 | key | The key 'key' has been initialized with hard-coded values from $@. | cryptoswift.swift:92:26:92:121 | [...] | [...] | +| cryptoswift.swift:152:26:152:26 | key | cryptoswift.swift:92:26:92:121 | [...] | cryptoswift.swift:152:26:152:26 | key | The key 'key' has been initialized with hard-coded values from $@. | cryptoswift.swift:92:26:92:121 | [...] | [...] | +| cryptoswift.swift:153:26:153:26 | key | cryptoswift.swift:92:26:92:121 | [...] | cryptoswift.swift:153:26:153:26 | key | The key 'key' has been initialized with hard-coded values from $@. | cryptoswift.swift:92:26:92:121 | [...] | [...] | +| cryptoswift.swift:154:26:154:26 | keyString | cryptoswift.swift:78:2:78:2 | this string is constant | cryptoswift.swift:154:26:154:26 | keyString | The key 'keyString' has been initialized with hard-coded values from $@. | cryptoswift.swift:78:2:78:2 | this string is constant | this string is constant | +| cryptoswift.swift:155:26:155:26 | keyString | cryptoswift.swift:78:2:78:2 | this string is constant | cryptoswift.swift:155:26:155:26 | keyString | The key 'keyString' has been initialized with hard-coded values from $@. | cryptoswift.swift:78:2:78:2 | this string is constant | this string is constant | +| cryptoswift.swift:163:24:163:24 | key | cryptoswift.swift:92:26:92:121 | [...] | cryptoswift.swift:163:24:163:24 | key | The key 'key' has been initialized with hard-coded values from $@. | cryptoswift.swift:92:26:92:121 | [...] | [...] | +| cryptoswift.swift:164:24:164:24 | keyString | cryptoswift.swift:78:2:78:2 | this string is constant | cryptoswift.swift:164:24:164:24 | keyString | The key 'keyString' has been initialized with hard-coded values from $@. | cryptoswift.swift:78:2:78:2 | this string is constant | this string is constant | +| cryptoswift.swift:165:24:165:24 | key | cryptoswift.swift:92:26:92:121 | [...] | cryptoswift.swift:165:24:165:24 | key | The key 'key' has been initialized with hard-coded values from $@. | cryptoswift.swift:92:26:92:121 | [...] | [...] | +| cryptoswift.swift:166:24:166:24 | keyString | cryptoswift.swift:78:2:78:2 | this string is constant | cryptoswift.swift:166:24:166:24 | keyString | The key 'keyString' has been initialized with hard-coded values from $@. | cryptoswift.swift:78:2:78:2 | this string is constant | this string is constant | | file://:0:0:0:0 | [post] self | misc.swift:46:24:46:24 | abcdef123456 | file://:0:0:0:0 | [post] self | The key '[post] self' has been initialized with hard-coded values from $@. | misc.swift:46:24:46:24 | abcdef123456 | abcdef123456 | | grdb.swift:27:23:27:23 | constString | grdb.swift:21:20:21:20 | abc123 | grdb.swift:27:23:27:23 | constString | The key 'constString' has been initialized with hard-coded values from $@. | grdb.swift:21:20:21:20 | abc123 | abc123 | | grdb.swift:29:23:29:23 | constData | grdb.swift:22:33:22:50 | [...] | grdb.swift:29:23:29:23 | constData | The key 'constData' has been initialized with hard-coded values from $@. | grdb.swift:22:33:22:50 | [...] | [...] | diff --git a/swift/ql/test/query-tests/Security/CWE-321/cryptoswift.swift b/swift/ql/test/query-tests/Security/CWE-321/cryptoswift.swift index 46d3981e19a1..771546a6488e 100644 --- a/swift/ql/test/query-tests/Security/CWE-321/cryptoswift.swift +++ b/swift/ql/test/query-tests/Security/CWE-321/cryptoswift.swift @@ -8,6 +8,8 @@ class AES init(key: Array, blockMode: BlockMode) { } init(key: String, iv: String) { } init(key: String, iv: String, padding: Padding) { } + + public static let blockSize: Int = 16 } class Blowfish @@ -62,18 +64,18 @@ enum Variant { protocol BlockMode { } struct CBC: BlockMode { - init() { } + init(iv: Array) { } } protocol PaddingProtocol { } enum Padding: PaddingProtocol { - case noPadding, zeroPadding, pkcs7, pkcs5, eme_pkcs1v15, emsa_pkcs1v15, iso78164, iso10126 + case noPadding, zeroPadding, pkcs7, pkcs5, eme_pkcs1v15, emsa_pkcs1v15, iso78164, iso10126 } // Helper functions func getConstantString() -> String { - "this string is constant" + "this string is constant" } func getConstantArray() -> Array { @@ -95,7 +97,7 @@ func test() { let randomKey = getRandomArray() let randomKeyString = String(cString: getRandomArray()) - let blockMode = CBC() + let blockMode = CBC(iv: getRandomArray()) let padding = Padding.noPadding let variant = Variant.sha2 diff --git a/swift/ql/test/query-tests/Security/CWE-327/ECBEncryption.expected b/swift/ql/test/query-tests/Security/CWE-327/ECBEncryption.expected index dce2964652cf..32c4082abb92 100644 --- a/swift/ql/test/query-tests/Security/CWE-327/ECBEncryption.expected +++ b/swift/ql/test/query-tests/Security/CWE-327/ECBEncryption.expected @@ -1,30 +1,30 @@ edges -| test.swift:34:9:34:13 | call to ECB.init() | test.swift:54:37:54:53 | call to getECBBlockMode() | provenance | | -| test.swift:34:9:34:13 | call to ECB.init() | test.swift:55:37:55:53 | call to getECBBlockMode() | provenance | | -| test.swift:34:9:34:13 | call to ECB.init() | test.swift:67:42:67:58 | call to getECBBlockMode() | provenance | | -| test.swift:45:12:45:16 | call to ECB.init() | test.swift:50:37:50:37 | ecb | provenance | | -| test.swift:45:12:45:16 | call to ECB.init() | test.swift:51:37:51:37 | ecb | provenance | | -| test.swift:45:12:45:16 | call to ECB.init() | test.swift:65:42:65:42 | ecb | provenance | | +| test.swift:39:9:39:13 | call to ECB.init() | test.swift:60:37:60:53 | call to getECBBlockMode() | provenance | | +| test.swift:39:9:39:13 | call to ECB.init() | test.swift:61:37:61:53 | call to getECBBlockMode() | provenance | | +| test.swift:39:9:39:13 | call to ECB.init() | test.swift:73:42:73:58 | call to getECBBlockMode() | provenance | | +| test.swift:50:12:50:16 | call to ECB.init() | test.swift:56:37:56:37 | ecb | provenance | | +| test.swift:50:12:50:16 | call to ECB.init() | test.swift:57:37:57:37 | ecb | provenance | | +| test.swift:50:12:50:16 | call to ECB.init() | test.swift:71:42:71:42 | ecb | provenance | | nodes -| test.swift:34:9:34:13 | call to ECB.init() | semmle.label | call to ECB.init() | -| test.swift:45:12:45:16 | call to ECB.init() | semmle.label | call to ECB.init() | -| test.swift:50:37:50:37 | ecb | semmle.label | ecb | -| test.swift:51:37:51:37 | ecb | semmle.label | ecb | -| test.swift:52:37:52:41 | call to ECB.init() | semmle.label | call to ECB.init() | -| test.swift:53:37:53:41 | call to ECB.init() | semmle.label | call to ECB.init() | -| test.swift:54:37:54:53 | call to getECBBlockMode() | semmle.label | call to getECBBlockMode() | -| test.swift:55:37:55:53 | call to getECBBlockMode() | semmle.label | call to getECBBlockMode() | -| test.swift:65:42:65:42 | ecb | semmle.label | ecb | -| test.swift:66:42:66:46 | call to ECB.init() | semmle.label | call to ECB.init() | -| test.swift:67:42:67:58 | call to getECBBlockMode() | semmle.label | call to getECBBlockMode() | +| test.swift:39:9:39:13 | call to ECB.init() | semmle.label | call to ECB.init() | +| test.swift:50:12:50:16 | call to ECB.init() | semmle.label | call to ECB.init() | +| test.swift:56:37:56:37 | ecb | semmle.label | ecb | +| test.swift:57:37:57:37 | ecb | semmle.label | ecb | +| test.swift:58:37:58:41 | call to ECB.init() | semmle.label | call to ECB.init() | +| test.swift:59:37:59:41 | call to ECB.init() | semmle.label | call to ECB.init() | +| test.swift:60:37:60:53 | call to getECBBlockMode() | semmle.label | call to getECBBlockMode() | +| test.swift:61:37:61:53 | call to getECBBlockMode() | semmle.label | call to getECBBlockMode() | +| test.swift:71:42:71:42 | ecb | semmle.label | ecb | +| test.swift:72:42:72:46 | call to ECB.init() | semmle.label | call to ECB.init() | +| test.swift:73:42:73:58 | call to getECBBlockMode() | semmle.label | call to getECBBlockMode() | subpaths #select -| test.swift:50:37:50:37 | ecb | test.swift:45:12:45:16 | call to ECB.init() | test.swift:50:37:50:37 | ecb | The initialization of the cipher 'ecb' uses the insecure ECB block mode from $@. | test.swift:45:12:45:16 | call to ECB.init() | call to ECB.init() | -| test.swift:51:37:51:37 | ecb | test.swift:45:12:45:16 | call to ECB.init() | test.swift:51:37:51:37 | ecb | The initialization of the cipher 'ecb' uses the insecure ECB block mode from $@. | test.swift:45:12:45:16 | call to ECB.init() | call to ECB.init() | -| test.swift:52:37:52:41 | call to ECB.init() | test.swift:52:37:52:41 | call to ECB.init() | test.swift:52:37:52:41 | call to ECB.init() | The initialization of the cipher 'call to ECB.init()' uses the insecure ECB block mode from $@. | test.swift:52:37:52:41 | call to ECB.init() | call to ECB.init() | -| test.swift:53:37:53:41 | call to ECB.init() | test.swift:53:37:53:41 | call to ECB.init() | test.swift:53:37:53:41 | call to ECB.init() | The initialization of the cipher 'call to ECB.init()' uses the insecure ECB block mode from $@. | test.swift:53:37:53:41 | call to ECB.init() | call to ECB.init() | -| test.swift:54:37:54:53 | call to getECBBlockMode() | test.swift:34:9:34:13 | call to ECB.init() | test.swift:54:37:54:53 | call to getECBBlockMode() | The initialization of the cipher 'call to getECBBlockMode()' uses the insecure ECB block mode from $@. | test.swift:34:9:34:13 | call to ECB.init() | call to ECB.init() | -| test.swift:55:37:55:53 | call to getECBBlockMode() | test.swift:34:9:34:13 | call to ECB.init() | test.swift:55:37:55:53 | call to getECBBlockMode() | The initialization of the cipher 'call to getECBBlockMode()' uses the insecure ECB block mode from $@. | test.swift:34:9:34:13 | call to ECB.init() | call to ECB.init() | -| test.swift:65:42:65:42 | ecb | test.swift:45:12:45:16 | call to ECB.init() | test.swift:65:42:65:42 | ecb | The initialization of the cipher 'ecb' uses the insecure ECB block mode from $@. | test.swift:45:12:45:16 | call to ECB.init() | call to ECB.init() | -| test.swift:66:42:66:46 | call to ECB.init() | test.swift:66:42:66:46 | call to ECB.init() | test.swift:66:42:66:46 | call to ECB.init() | The initialization of the cipher 'call to ECB.init()' uses the insecure ECB block mode from $@. | test.swift:66:42:66:46 | call to ECB.init() | call to ECB.init() | -| test.swift:67:42:67:58 | call to getECBBlockMode() | test.swift:34:9:34:13 | call to ECB.init() | test.swift:67:42:67:58 | call to getECBBlockMode() | The initialization of the cipher 'call to getECBBlockMode()' uses the insecure ECB block mode from $@. | test.swift:34:9:34:13 | call to ECB.init() | call to ECB.init() | +| test.swift:56:37:56:37 | ecb | test.swift:50:12:50:16 | call to ECB.init() | test.swift:56:37:56:37 | ecb | The initialization of the cipher 'ecb' uses the insecure ECB block mode from $@. | test.swift:50:12:50:16 | call to ECB.init() | call to ECB.init() | +| test.swift:57:37:57:37 | ecb | test.swift:50:12:50:16 | call to ECB.init() | test.swift:57:37:57:37 | ecb | The initialization of the cipher 'ecb' uses the insecure ECB block mode from $@. | test.swift:50:12:50:16 | call to ECB.init() | call to ECB.init() | +| test.swift:58:37:58:41 | call to ECB.init() | test.swift:58:37:58:41 | call to ECB.init() | test.swift:58:37:58:41 | call to ECB.init() | The initialization of the cipher 'call to ECB.init()' uses the insecure ECB block mode from $@. | test.swift:58:37:58:41 | call to ECB.init() | call to ECB.init() | +| test.swift:59:37:59:41 | call to ECB.init() | test.swift:59:37:59:41 | call to ECB.init() | test.swift:59:37:59:41 | call to ECB.init() | The initialization of the cipher 'call to ECB.init()' uses the insecure ECB block mode from $@. | test.swift:59:37:59:41 | call to ECB.init() | call to ECB.init() | +| test.swift:60:37:60:53 | call to getECBBlockMode() | test.swift:39:9:39:13 | call to ECB.init() | test.swift:60:37:60:53 | call to getECBBlockMode() | The initialization of the cipher 'call to getECBBlockMode()' uses the insecure ECB block mode from $@. | test.swift:39:9:39:13 | call to ECB.init() | call to ECB.init() | +| test.swift:61:37:61:53 | call to getECBBlockMode() | test.swift:39:9:39:13 | call to ECB.init() | test.swift:61:37:61:53 | call to getECBBlockMode() | The initialization of the cipher 'call to getECBBlockMode()' uses the insecure ECB block mode from $@. | test.swift:39:9:39:13 | call to ECB.init() | call to ECB.init() | +| test.swift:71:42:71:42 | ecb | test.swift:50:12:50:16 | call to ECB.init() | test.swift:71:42:71:42 | ecb | The initialization of the cipher 'ecb' uses the insecure ECB block mode from $@. | test.swift:50:12:50:16 | call to ECB.init() | call to ECB.init() | +| test.swift:72:42:72:46 | call to ECB.init() | test.swift:72:42:72:46 | call to ECB.init() | test.swift:72:42:72:46 | call to ECB.init() | The initialization of the cipher 'call to ECB.init()' uses the insecure ECB block mode from $@. | test.swift:72:42:72:46 | call to ECB.init() | call to ECB.init() | +| test.swift:73:42:73:58 | call to getECBBlockMode() | test.swift:39:9:39:13 | call to ECB.init() | test.swift:73:42:73:58 | call to getECBBlockMode() | The initialization of the cipher 'call to getECBBlockMode()' uses the insecure ECB block mode from $@. | test.swift:39:9:39:13 | call to ECB.init() | call to ECB.init() | diff --git a/swift/ql/test/query-tests/Security/CWE-327/test.swift b/swift/ql/test/query-tests/Security/CWE-327/test.swift index 40bded116e1e..382269905612 100644 --- a/swift/ql/test/query-tests/Security/CWE-327/test.swift +++ b/swift/ql/test/query-tests/Security/CWE-327/test.swift @@ -15,12 +15,12 @@ class Blowfish protocol BlockMode { } -struct ECB: BlockMode { +struct ECB: BlockMode { init() { } } -struct CBC: BlockMode { - init() { } +struct CBC: BlockMode { + init(iv: Array) { } } protocol PaddingProtocol { } @@ -30,12 +30,17 @@ enum Padding: PaddingProtocol { } // Create some inter-procedural dependencies + +func getRandomArray() -> Array { + (0..<10).map({ _ in UInt8.random(in: 0...UInt8.max) }) +} + func getECBBlockMode() -> BlockMode { return ECB() } func getCBCBlockMode() -> BlockMode { - return CBC() + return CBC(iv: getRandomArray()) } // --- tests --- @@ -43,7 +48,8 @@ func getCBCBlockMode() -> BlockMode { func test1() { let key: Array = [0x2a, 0x3a, 0x80, 0x05, 0xaf, 0x46, 0x58, 0x2d, 0x66, 0x52, 0x10, 0xae, 0x86, 0xd3, 0x8e, 0x8f] let ecb = ECB() - let cbc = CBC() + let iv = getRandomArray() + let cbc = CBC(iv: iv) let padding = Padding.noPadding // AES test cases @@ -56,8 +62,8 @@ func test1() { let ag1 = AES(key: key, blockMode: cbc, padding: padding) // GOOD let ag2 = AES(key: key, blockMode: cbc) // GOOD - let ag3 = AES(key: key, blockMode: CBC(), padding: padding) // GOOD - let ag4 = AES(key: key, blockMode: CBC()) // GOOD + let ag3 = AES(key: key, blockMode: CBC(iv: iv), padding: padding) // GOOD + let ag4 = AES(key: key, blockMode: CBC(iv: iv)) // GOOD let ag5 = AES(key: key, blockMode: getCBCBlockMode(), padding: padding) // GOOD let ag6 = AES(key: key, blockMode: getCBCBlockMode()) // GOOD @@ -67,6 +73,6 @@ func test1() { let bb3 = Blowfish(key: key, blockMode: getECBBlockMode(), padding: padding) // BAD let bg1 = Blowfish(key: key, blockMode: cbc, padding: padding) // GOOD - let bg2 = Blowfish(key: key, blockMode: CBC(), padding: padding) // GOOD + let bg2 = Blowfish(key: key, blockMode: CBC(iv: iv), padding: padding) // GOOD let bg3 = Blowfish(key: key, blockMode: getCBCBlockMode(), padding: padding) // GOOD } From 2486c8423be3c1943025ede83f4437e189708add Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 1 Aug 2024 17:02:03 +0100 Subject: [PATCH 4/6] Swift: Correct mistakes. --- .../src/queries/Security/CWE-311/CleartextStorageDatabase.swift | 2 +- .../ql/src/queries/Security/CWE-311/CleartextTransmission.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.swift b/swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.swift index eabcbb7eac22..64c3ef4e1109 100644 --- a/swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.swift +++ b/swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.swift @@ -5,7 +5,7 @@ private func encrypt(_ text: String, _ encryptionKey: SymmetricKey) -> String { return sealedBox.combined!.base64EncodedString() } -func storeMyData(databaseObject : NSManagedObject, faveSong : String, creditCardNo : String, key: SymmetricKey) { +func storeMyData(databaseObject : NSManagedObject, faveSong : String, creditCardNo : String, encryptionKey: SymmetricKey) { // ... // GOOD: not sensitive information diff --git a/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.swift b/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.swift index 62dda307935a..164c8fedc486 100644 --- a/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.swift +++ b/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.swift @@ -5,7 +5,7 @@ private func encrypt(_ text: String, _ encryptionKey: SymmetricKey) -> String { return sealedBox.combined!.base64EncodedString() } -func transmitMyData(connection : NWConnection, faveSong : String, creditCardNo : String, key: SymmetricKey) { +func transmitMyData(connection : NWConnection, faveSong : String, creditCardNo : String, encryptionKey: SymmetricKey) { // ... // GOOD: not sensitive information From d3cdffef6180cb01706527f7d76ae163caf2b0a4 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 2 Aug 2024 12:07:31 +0100 Subject: [PATCH 5/6] Apply suggestions from code review Co-authored-by: Ben Ahmady <32935794+subatoi@users.noreply.github.com> --- .../src/queries/Security/CWE-311/CleartextStorageDatabase.qhelp | 2 +- .../ql/src/queries/Security/CWE-311/CleartextTransmission.qhelp | 2 +- .../queries/Security/CWE-312/CleartextStoragePreferences.qhelp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.qhelp b/swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.qhelp index b66885dc3692..e4ae8c9cfa83 100644 --- a/swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.qhelp +++ b/swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.qhelp @@ -12,7 +12,7 @@ -

    The following example shows three cases of storing information using the Core Data library. In the 'BAD' case, the data that is stored is sensitive (a credit card number) and is not encrypted. In the 'GOOD' cases, the data is either not sensitive, or is protected with encryption. When encryption is used, care must be taken to select a secure modern encryption algorithm and put suitable key management practices into place.

    +

    The following example shows three cases of storing information using the Core Data library. In the 'BAD' case, the data that is stored is sensitive (a credit card number) and is not encrypted. In the 'GOOD' cases, the data is either not sensitive, or is protected with encryption. When encryption is used, take care to select a secure modern encryption algorithm, and put suitable key management practices into place.

    diff --git a/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.qhelp b/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.qhelp index 2008072403ab..515d58e72214 100644 --- a/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.qhelp +++ b/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.qhelp @@ -12,7 +12,7 @@ -

    The following example shows three cases of transmitting information. In the 'BAD' case, the data transmitted is sensitive (a credit card number) and is not encrypted. In the 'GOOD' cases, the data is either not sensitive, or is protected with encryption. When encryption is used, care must be taken to select a secure modern encryption algorithm and put suitable key management practices into place.

    +

    The following example shows three cases of transmitting information. In the 'BAD' case, the data transmitted is sensitive (a credit card number) and is not encrypted. In the 'GOOD' cases, the data is either not sensitive, or is protected with encryption. When encryption is used, take care to select a secure modern encryption algorithm and put suitable key management practices into place.

    diff --git a/swift/ql/src/queries/Security/CWE-312/CleartextStoragePreferences.qhelp b/swift/ql/src/queries/Security/CWE-312/CleartextStoragePreferences.qhelp index da3c9d9a32f7..7af8d629aa03 100644 --- a/swift/ql/src/queries/Security/CWE-312/CleartextStoragePreferences.qhelp +++ b/swift/ql/src/queries/Security/CWE-312/CleartextStoragePreferences.qhelp @@ -12,7 +12,7 @@ -

    The following example shows three cases of storing information using UserDefaults. In the 'BAD' case, the data that is stored is sensitive (a credit card number) and is not encrypted. In the 'GOOD' cases, the data is either not sensitive, or is protected with encryption. When encryption is used, care must be taken to select a secure modern encryption algorithm and put suitable key management practices into place.

    +

    The following example shows three cases of storing information using UserDefaults. In the 'BAD' case, the data that is stored is sensitive (a credit card number) and is not encrypted. In the 'GOOD' cases, the data is either not sensitive, or is protected with encryption. When encryption is used, take care to select a secure modern encryption algorithm and put suitable key management practices into place.

    From 5a5fdb2f6bb190411d0fea7b8df645a973bd2c53 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 2 Aug 2024 12:11:35 +0100 Subject: [PATCH 6/6] Swift: I missed the commas. --- .../ql/src/queries/Security/CWE-311/CleartextTransmission.qhelp | 2 +- .../queries/Security/CWE-312/CleartextStoragePreferences.qhelp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.qhelp b/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.qhelp index 515d58e72214..653ba33aba4c 100644 --- a/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.qhelp +++ b/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.qhelp @@ -12,7 +12,7 @@ -

    The following example shows three cases of transmitting information. In the 'BAD' case, the data transmitted is sensitive (a credit card number) and is not encrypted. In the 'GOOD' cases, the data is either not sensitive, or is protected with encryption. When encryption is used, take care to select a secure modern encryption algorithm and put suitable key management practices into place.

    +

    The following example shows three cases of transmitting information. In the 'BAD' case, the data transmitted is sensitive (a credit card number) and is not encrypted. In the 'GOOD' cases, the data is either not sensitive, or is protected with encryption. When encryption is used, take care to select a secure modern encryption algorithm, and put suitable key management practices into place.

    diff --git a/swift/ql/src/queries/Security/CWE-312/CleartextStoragePreferences.qhelp b/swift/ql/src/queries/Security/CWE-312/CleartextStoragePreferences.qhelp index 7af8d629aa03..4ad73ed4872b 100644 --- a/swift/ql/src/queries/Security/CWE-312/CleartextStoragePreferences.qhelp +++ b/swift/ql/src/queries/Security/CWE-312/CleartextStoragePreferences.qhelp @@ -12,7 +12,7 @@ -

    The following example shows three cases of storing information using UserDefaults. In the 'BAD' case, the data that is stored is sensitive (a credit card number) and is not encrypted. In the 'GOOD' cases, the data is either not sensitive, or is protected with encryption. When encryption is used, take care to select a secure modern encryption algorithm and put suitable key management practices into place.

    +

    The following example shows three cases of storing information using UserDefaults. In the 'BAD' case, the data that is stored is sensitive (a credit card number) and is not encrypted. In the 'GOOD' cases, the data is either not sensitive, or is protected with encryption. When encryption is used, take care to select a secure modern encryption algorithm, and put suitable key management practices into place.