Skip to content

Commit 794ba42

Browse files
authored
Merge pull request github#11942 from geoffw0/rncrypt4
Swift: add RNCryptor sinks to swift/static-initialization-vector
2 parents 812306c + f05be77 commit 794ba42

File tree

3 files changed

+142
-2
lines changed

3 files changed

+142
-2
lines changed

swift/ql/src/queries/Security/CWE-1204/StaticInitializationVector.ql

+11-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@ import DataFlow::PathGraph
2121
*/
2222
class StaticInitializationVectorSource extends Expr {
2323
StaticInitializationVectorSource() {
24-
this = any(ArrayExpr arr | arr.getType().getName() = "Array<UInt8>") or
25-
this instanceof StringLiteralExpr
24+
this instanceof ArrayExpr or
25+
this instanceof StringLiteralExpr or
26+
this instanceof NumberLiteralExpr
2627
}
2728
}
2829

@@ -40,6 +41,14 @@ class EncryptionInitializationSink extends Expr {
4041
], _) and
4142
call.getArgumentWithLabel("iv").getExpr() = this
4243
)
44+
or
45+
// RNCryptor
46+
exists(ClassOrStructDecl c, MethodDecl f, CallExpr call |
47+
c.getFullName() = ["RNCryptor", "RNEncryptor", "RNDecryptor"] and
48+
c.getAMember() = f and
49+
call.getStaticTarget() = f and
50+
call.getArgumentWithLabel(["iv", "IV"]).getExpr() = this
51+
)
4352
}
4453
}
4554

swift/ql/test/query-tests/Security/CWE-1204/StaticInitializationVector.expected

+47
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,21 @@
11
edges
2+
| rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) : |
3+
| rncryptor.swift:60:19:60:25 | call to Data.init(_:) : | rncryptor.swift:68:104:68:104 | myConstIV1 |
4+
| rncryptor.swift:60:19:60:25 | call to Data.init(_:) : | rncryptor.swift:77:125:77:125 | myConstIV1 |
5+
| rncryptor.swift:60:24:60:24 | 0 : | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) : |
6+
| rncryptor.swift:60:24:60:24 | 0 : | rncryptor.swift:60:19:60:25 | call to Data.init(_:) : |
7+
| rncryptor.swift:61:19:61:27 | call to Data.init(_:) : | rncryptor.swift:70:104:70:104 | myConstIV2 |
8+
| rncryptor.swift:61:19:61:27 | call to Data.init(_:) : | rncryptor.swift:79:133:79:133 | myConstIV2 |
9+
| rncryptor.swift:61:24:61:24 | 123 : | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) : |
10+
| rncryptor.swift:61:24:61:24 | 123 : | rncryptor.swift:61:19:61:27 | call to Data.init(_:) : |
11+
| rncryptor.swift:62:19:62:35 | call to Data.init(_:) : | rncryptor.swift:72:84:72:84 | myConstIV3 |
12+
| rncryptor.swift:62:19:62:35 | call to Data.init(_:) : | rncryptor.swift:81:105:81:105 | myConstIV3 |
13+
| rncryptor.swift:62:24:62:34 | [...] : | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) : |
14+
| rncryptor.swift:62:24:62:34 | [...] : | rncryptor.swift:62:19:62:35 | call to Data.init(_:) : |
15+
| rncryptor.swift:63:19:63:28 | call to Data.init(_:) : | rncryptor.swift:74:84:74:84 | myConstIV4 |
16+
| rncryptor.swift:63:19:63:28 | call to Data.init(_:) : | rncryptor.swift:83:113:83:113 | myConstIV4 |
17+
| rncryptor.swift:63:24:63:24 | iv : | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) : |
18+
| rncryptor.swift:63:24:63:24 | iv : | rncryptor.swift:63:19:63:28 | call to Data.init(_:) : |
219
| test.swift:53:19:53:34 | iv : | test.swift:54:17:54:17 | iv |
320
| test.swift:85:3:85:3 | this string is constant : | test.swift:101:17:101:35 | call to getConstantString() : |
421
| test.swift:99:25:99:120 | [...] : | test.swift:128:33:128:33 | iv |
@@ -23,6 +40,24 @@ edges
2340
| test.swift:101:17:101:35 | call to getConstantString() : | test.swift:130:39:130:39 | ivString |
2441
| test.swift:147:22:147:22 | iv : | test.swift:53:19:53:34 | iv : |
2542
nodes
43+
| file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) : | semmle.label | [summary] to write: return (return) in Data.init(_:) : |
44+
| rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) : | semmle.label | [summary param] 0 in Data.init(_:) : |
45+
| rncryptor.swift:60:19:60:25 | call to Data.init(_:) : | semmle.label | call to Data.init(_:) : |
46+
| rncryptor.swift:60:24:60:24 | 0 : | semmle.label | 0 : |
47+
| rncryptor.swift:61:19:61:27 | call to Data.init(_:) : | semmle.label | call to Data.init(_:) : |
48+
| rncryptor.swift:61:24:61:24 | 123 : | semmle.label | 123 : |
49+
| rncryptor.swift:62:19:62:35 | call to Data.init(_:) : | semmle.label | call to Data.init(_:) : |
50+
| rncryptor.swift:62:24:62:34 | [...] : | semmle.label | [...] : |
51+
| rncryptor.swift:63:19:63:28 | call to Data.init(_:) : | semmle.label | call to Data.init(_:) : |
52+
| rncryptor.swift:63:24:63:24 | iv : | semmle.label | iv : |
53+
| rncryptor.swift:68:104:68:104 | myConstIV1 | semmle.label | myConstIV1 |
54+
| rncryptor.swift:70:104:70:104 | myConstIV2 | semmle.label | myConstIV2 |
55+
| rncryptor.swift:72:84:72:84 | myConstIV3 | semmle.label | myConstIV3 |
56+
| rncryptor.swift:74:84:74:84 | myConstIV4 | semmle.label | myConstIV4 |
57+
| rncryptor.swift:77:125:77:125 | myConstIV1 | semmle.label | myConstIV1 |
58+
| rncryptor.swift:79:133:79:133 | myConstIV2 | semmle.label | myConstIV2 |
59+
| rncryptor.swift:81:105:81:105 | myConstIV3 | semmle.label | myConstIV3 |
60+
| rncryptor.swift:83:113:83:113 | myConstIV4 | semmle.label | myConstIV4 |
2661
| test.swift:53:19:53:34 | iv : | semmle.label | iv : |
2762
| test.swift:54:17:54:17 | iv | semmle.label | iv |
2863
| test.swift:85:3:85:3 | this string is constant : | semmle.label | this string is constant : |
@@ -49,7 +84,19 @@ nodes
4984
| test.swift:167:22:167:22 | iv | semmle.label | iv |
5085
| test.swift:168:22:168:22 | iv | semmle.label | iv |
5186
subpaths
87+
| rncryptor.swift:60:24:60:24 | 0 : | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) : | rncryptor.swift:60:19:60:25 | call to Data.init(_:) : |
88+
| rncryptor.swift:61:24:61:24 | 123 : | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) : | rncryptor.swift:61:19:61:27 | call to Data.init(_:) : |
89+
| rncryptor.swift:62:24:62:34 | [...] : | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) : | rncryptor.swift:62:19:62:35 | call to Data.init(_:) : |
90+
| rncryptor.swift:63:24:63:24 | iv : | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) : | rncryptor.swift:63:19:63:28 | call to Data.init(_:) : |
5291
#select
92+
| rncryptor.swift:68:104:68:104 | myConstIV1 | rncryptor.swift:60:24:60:24 | 0 : | rncryptor.swift:68:104:68:104 | myConstIV1 | The static value '0' is used as an initialization vector for encryption. |
93+
| rncryptor.swift:70:104:70:104 | myConstIV2 | rncryptor.swift:61:24:61:24 | 123 : | rncryptor.swift:70:104:70:104 | myConstIV2 | The static value '123' is used as an initialization vector for encryption. |
94+
| rncryptor.swift:72:84:72:84 | myConstIV3 | rncryptor.swift:62:24:62:34 | [...] : | rncryptor.swift:72:84:72:84 | myConstIV3 | The static value '[...]' is used as an initialization vector for encryption. |
95+
| rncryptor.swift:74:84:74:84 | myConstIV4 | rncryptor.swift:63:24:63:24 | iv : | rncryptor.swift:74:84:74:84 | myConstIV4 | The static value 'iv' is used as an initialization vector for encryption. |
96+
| rncryptor.swift:77:125:77:125 | myConstIV1 | rncryptor.swift:60:24:60:24 | 0 : | rncryptor.swift:77:125:77:125 | myConstIV1 | The static value '0' is used as an initialization vector for encryption. |
97+
| rncryptor.swift:79:133:79:133 | myConstIV2 | rncryptor.swift:61:24:61:24 | 123 : | rncryptor.swift:79:133:79:133 | myConstIV2 | The static value '123' is used as an initialization vector for encryption. |
98+
| rncryptor.swift:81:105:81:105 | myConstIV3 | rncryptor.swift:62:24:62:34 | [...] : | rncryptor.swift:81:105:81:105 | myConstIV3 | The static value '[...]' is used as an initialization vector for encryption. |
99+
| rncryptor.swift:83:113:83:113 | myConstIV4 | rncryptor.swift:63:24:63:24 | iv : | rncryptor.swift:83:113:83:113 | myConstIV4 | The static value 'iv' is used as an initialization vector for encryption. |
53100
| test.swift:54:17:54:17 | iv | test.swift:99:25:99:120 | [...] : | test.swift:54:17:54:17 | iv | The static value '[...]' is used as an initialization vector for encryption. |
54101
| test.swift:112:36:112:36 | ivString | test.swift:85:3:85:3 | this string is constant : | test.swift:112:36:112:36 | ivString | The static value 'this string is constant' is used as an initialization vector for encryption. |
55102
| test.swift:113:36:113:36 | ivString | test.swift:85:3:85:3 | this string is constant : | test.swift:113:36:113:36 | ivString | The static value 'this string is constant' is used as an initialization vector for encryption. |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
2+
// --- stubs ---
3+
4+
class Data {
5+
init<S>(_ elements: S) {}
6+
}
7+
8+
class NSObject
9+
{
10+
}
11+
12+
struct _RNCryptorSettings {
13+
// ...
14+
}
15+
typealias RNCryptorSettings = _RNCryptorSettings
16+
17+
let kRNCryptorAES256Settings = RNCryptorSettings()
18+
19+
struct _RNCryptorKeyDerivationSettings {
20+
// ...
21+
}
22+
typealias RNCryptorKeyDerivationSettings = _RNCryptorKeyDerivationSettings
23+
24+
typealias RNCryptorHandler = () -> Void // simplified
25+
26+
class RNCryptor : NSObject
27+
{
28+
}
29+
30+
class RNEncryptor : RNCryptor
31+
{
32+
override init() {}
33+
34+
init(settings theSettings: RNCryptorSettings, encryptionKey anEncryptionKey: Data?, hmacKey anHMACKey: Data?, iv anIV: Data?, handler aHandler: RNCryptorHandler?) {}
35+
init(settings theSettings: RNCryptorSettings, encryptionKey anEncryptionKey: Data?, HMACKey anHMACKey: Data?, IV anIV: Data?, handler aHandler: RNCryptorHandler?) {}
36+
init(settings: RNCryptorSettings, password: String, iv anIV: Data?, encryptionSalt anEncryptionSalt: Data?, hmacSalt anHMACSalt: Data?, handler: RNCryptorHandler?) {}
37+
init(settings: RNCryptorSettings, password: String, IV anIV: Data?, encryptionSalt anEncryptionSalt: Data?, HMACSalt anHMACSalt: Data?, handler: RNCryptorHandler?) {}
38+
39+
func encryptData(_ thePlaintext: Data?, with theSettings: RNCryptorSettings, encryptionKey anEncryptionKey: Data?, hmacKey anHMACKey: Data?, iv anIV: Data?) throws -> Data { return Data(0) }
40+
func encryptData(_ thePlaintext: Data?, withSettings theSettings: RNCryptorSettings, encryptionKey anEncryptionKey: Data?, HMACKey anHMACKey: Data?, IV anIV: Data?) throws -> Data { return Data(0) }
41+
func encryptData(_ data: Data?, with settings: RNCryptorSettings, password: String?, iv anIV: Data?, encryptionSalt anEncryptionSalt: Data?, hmacSalt anHMACSalt: Data?) throws -> Data { return Data(0) }
42+
func encryptData(_ data: Data?, withSettings settings: RNCryptorSettings, password: String?, IV anIV: Data?, encryptionSalt anEncryptionSalt: Data?, HMACSalt anHMACSalt: Data?) throws -> Data { return Data(0) }
43+
}
44+
45+
// --- tests ---
46+
47+
func getRandomArray() -> [UInt8] {
48+
(0..<12).map({ _ in UInt8.random(in: 0...UInt8.max) })
49+
}
50+
51+
func test(myPassword: String) {
52+
// RNCryptor
53+
let myEncryptor = RNEncryptor()
54+
let myData = Data(0)
55+
let myKey = Data(0)
56+
let myHMACKey = Data(0)
57+
let myKeyDerivationSettings = RNCryptorKeyDerivationSettings()
58+
let myHandler = {}
59+
let myRandomIV = Data(getRandomArray())
60+
let myConstIV1 = Data(0)
61+
let myConstIV2 = Data(123)
62+
let myConstIV3 = Data([1,2,3,4,5])
63+
let myConstIV4 = Data("iv")
64+
let mySalt = Data(0)
65+
let mySalt2 = Data(0)
66+
67+
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, encryptionKey: myKey, hmacKey: myHMACKey, iv: myRandomIV, handler: myHandler) // GOOD
68+
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, encryptionKey: myKey, hmacKey: myHMACKey, iv: myConstIV1, handler: myHandler) // BAD
69+
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, encryptionKey: myKey, HMACKey: myHMACKey, IV: myRandomIV, handler: myHandler) // GOOD
70+
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, encryptionKey: myKey, HMACKey: myHMACKey, IV: myConstIV2, handler: myHandler) // BAD
71+
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, iv: myRandomIV, encryptionSalt: mySalt, hmacSalt: mySalt2, handler: myHandler) // GOOD
72+
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, iv: myConstIV3, encryptionSalt: mySalt, hmacSalt: mySalt2, handler: myHandler) // BAD
73+
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, IV: myRandomIV, encryptionSalt: mySalt, HMACSalt: mySalt2, handler: myHandler) // GOOD
74+
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, IV: myConstIV4, encryptionSalt: mySalt, HMACSalt: mySalt2, handler: myHandler) // BAD
75+
76+
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, encryptionKey: myKey, hmacKey: myHMACKey, iv: myRandomIV) // GOOD
77+
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, encryptionKey: myKey, hmacKey: myHMACKey, iv: myConstIV1) // BAD
78+
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, encryptionKey: myKey, HMACKey: myHMACKey, IV: myRandomIV) // GOOD
79+
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, encryptionKey: myKey, HMACKey: myHMACKey, IV: myConstIV2) // BAD
80+
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myPassword, iv: myRandomIV, encryptionSalt: mySalt, hmacSalt: mySalt2) // GOOD
81+
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myPassword, iv: myConstIV3, encryptionSalt: mySalt, hmacSalt: mySalt2) // BAD
82+
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, password: myPassword, IV: myRandomIV, encryptionSalt: mySalt, HMACSalt: mySalt2) // GOOD
83+
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, password: myPassword, IV: myConstIV4, encryptionSalt: mySalt, HMACSalt: mySalt2) // BAD
84+
}

0 commit comments

Comments
 (0)