Skip to content

Commit 6be01ea

Browse files
committed
Swift: Add implict read steps for dictionary content.
1 parent 4350060 commit 6be01ea

File tree

3 files changed

+63
-6
lines changed

3 files changed

+63
-6
lines changed

swift/ql/lib/codeql/swift/security/CleartextStorageDatabaseQuery.qll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,15 @@ module CleartextStorageDatabaseConfig implements DataFlow::ConfigSig {
3939
cx.asNominalTypeDecl() = d and
4040
c.getAReadContent().(DataFlow::Content::FieldContent).getField() = cx.getAMember()
4141
)
42+
or
43+
// flow out from dictionary values at the sink (this is essential for some of the
44+
// SQLite.swift models)
45+
isSink(node) and
46+
node.asExpr().getType().getUnderlyingType() instanceof DictionaryType and
47+
(
48+
c.getAReadContent() instanceof DataFlow::Content::CollectionContent or
49+
c.getAReadContent().(DataFlow::Content::TupleContent).getIndex() = 1
50+
)
4251
}
4352
}
4453

swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,24 @@ edges
2727
| SQLite.swift:156:22:156:22 | mobilePhoneNumber | SQLite.swift:156:21:156:43 | [...] |
2828
| SQLite.swift:157:21:157:21 | mobilePhoneNumber | SQLite.swift:157:20:157:42 | [...] |
2929
| SQLite.swift:158:24:158:24 | mobilePhoneNumber | SQLite.swift:158:23:158:45 | [...] |
30+
| SQLite.swift:162:32:162:70 | [...] [Collection element, Tuple element at index 1] | SQLite.swift:162:32:162:70 | [...] |
31+
| SQLite.swift:162:43:162:53 | (...) [Tuple element at index 1] | SQLite.swift:162:32:162:70 | [...] [Collection element, Tuple element at index 1] |
32+
| SQLite.swift:162:53:162:53 | mobilePhoneNumber | SQLite.swift:162:43:162:53 | (...) [Tuple element at index 1] |
33+
| SQLite.swift:163:28:163:66 | [...] [Collection element, Tuple element at index 1] | SQLite.swift:163:28:163:66 | [...] |
34+
| SQLite.swift:163:39:163:49 | (...) [Tuple element at index 1] | SQLite.swift:163:28:163:66 | [...] [Collection element, Tuple element at index 1] |
35+
| SQLite.swift:163:49:163:49 | mobilePhoneNumber | SQLite.swift:163:39:163:49 | (...) [Tuple element at index 1] |
36+
| SQLite.swift:164:31:164:69 | [...] [Collection element, Tuple element at index 1] | SQLite.swift:164:31:164:69 | [...] |
37+
| SQLite.swift:164:42:164:52 | (...) [Tuple element at index 1] | SQLite.swift:164:31:164:69 | [...] [Collection element, Tuple element at index 1] |
38+
| SQLite.swift:164:52:164:52 | mobilePhoneNumber | SQLite.swift:164:42:164:52 | (...) [Tuple element at index 1] |
39+
| SQLite.swift:167:21:167:59 | [...] [Collection element, Tuple element at index 1] | SQLite.swift:167:21:167:59 | [...] |
40+
| SQLite.swift:167:32:167:42 | (...) [Tuple element at index 1] | SQLite.swift:167:21:167:59 | [...] [Collection element, Tuple element at index 1] |
41+
| SQLite.swift:167:42:167:42 | mobilePhoneNumber | SQLite.swift:167:32:167:42 | (...) [Tuple element at index 1] |
42+
| SQLite.swift:168:20:168:58 | [...] [Collection element, Tuple element at index 1] | SQLite.swift:168:20:168:58 | [...] |
43+
| SQLite.swift:168:31:168:41 | (...) [Tuple element at index 1] | SQLite.swift:168:20:168:58 | [...] [Collection element, Tuple element at index 1] |
44+
| SQLite.swift:168:41:168:41 | mobilePhoneNumber | SQLite.swift:168:31:168:41 | (...) [Tuple element at index 1] |
45+
| SQLite.swift:169:23:169:61 | [...] [Collection element, Tuple element at index 1] | SQLite.swift:169:23:169:61 | [...] |
46+
| SQLite.swift:169:34:169:44 | (...) [Tuple element at index 1] | SQLite.swift:169:23:169:61 | [...] [Collection element, Tuple element at index 1] |
47+
| SQLite.swift:169:44:169:44 | mobilePhoneNumber | SQLite.swift:169:34:169:44 | (...) [Tuple element at index 1] |
3048
| file://:0:0:0:0 | self | file://:0:0:0:0 | .value |
3149
| file://:0:0:0:0 | self | file://:0:0:0:0 | .value2 |
3250
| file://:0:0:0:0 | self [value] | file://:0:0:0:0 | .value |
@@ -255,6 +273,30 @@ nodes
255273
| SQLite.swift:157:21:157:21 | mobilePhoneNumber | semmle.label | mobilePhoneNumber |
256274
| SQLite.swift:158:23:158:45 | [...] | semmle.label | [...] |
257275
| SQLite.swift:158:24:158:24 | mobilePhoneNumber | semmle.label | mobilePhoneNumber |
276+
| SQLite.swift:162:32:162:70 | [...] | semmle.label | [...] |
277+
| SQLite.swift:162:32:162:70 | [...] [Collection element, Tuple element at index 1] | semmle.label | [...] [Collection element, Tuple element at index 1] |
278+
| SQLite.swift:162:43:162:53 | (...) [Tuple element at index 1] | semmle.label | (...) [Tuple element at index 1] |
279+
| SQLite.swift:162:53:162:53 | mobilePhoneNumber | semmle.label | mobilePhoneNumber |
280+
| SQLite.swift:163:28:163:66 | [...] | semmle.label | [...] |
281+
| SQLite.swift:163:28:163:66 | [...] [Collection element, Tuple element at index 1] | semmle.label | [...] [Collection element, Tuple element at index 1] |
282+
| SQLite.swift:163:39:163:49 | (...) [Tuple element at index 1] | semmle.label | (...) [Tuple element at index 1] |
283+
| SQLite.swift:163:49:163:49 | mobilePhoneNumber | semmle.label | mobilePhoneNumber |
284+
| SQLite.swift:164:31:164:69 | [...] | semmle.label | [...] |
285+
| SQLite.swift:164:31:164:69 | [...] [Collection element, Tuple element at index 1] | semmle.label | [...] [Collection element, Tuple element at index 1] |
286+
| SQLite.swift:164:42:164:52 | (...) [Tuple element at index 1] | semmle.label | (...) [Tuple element at index 1] |
287+
| SQLite.swift:164:52:164:52 | mobilePhoneNumber | semmle.label | mobilePhoneNumber |
288+
| SQLite.swift:167:21:167:59 | [...] | semmle.label | [...] |
289+
| SQLite.swift:167:21:167:59 | [...] [Collection element, Tuple element at index 1] | semmle.label | [...] [Collection element, Tuple element at index 1] |
290+
| SQLite.swift:167:32:167:42 | (...) [Tuple element at index 1] | semmle.label | (...) [Tuple element at index 1] |
291+
| SQLite.swift:167:42:167:42 | mobilePhoneNumber | semmle.label | mobilePhoneNumber |
292+
| SQLite.swift:168:20:168:58 | [...] | semmle.label | [...] |
293+
| SQLite.swift:168:20:168:58 | [...] [Collection element, Tuple element at index 1] | semmle.label | [...] [Collection element, Tuple element at index 1] |
294+
| SQLite.swift:168:31:168:41 | (...) [Tuple element at index 1] | semmle.label | (...) [Tuple element at index 1] |
295+
| SQLite.swift:168:41:168:41 | mobilePhoneNumber | semmle.label | mobilePhoneNumber |
296+
| SQLite.swift:169:23:169:61 | [...] | semmle.label | [...] |
297+
| SQLite.swift:169:23:169:61 | [...] [Collection element, Tuple element at index 1] | semmle.label | [...] [Collection element, Tuple element at index 1] |
298+
| SQLite.swift:169:34:169:44 | (...) [Tuple element at index 1] | semmle.label | (...) [Tuple element at index 1] |
299+
| SQLite.swift:169:44:169:44 | mobilePhoneNumber | semmle.label | mobilePhoneNumber |
258300
| file://:0:0:0:0 | .value | semmle.label | .value |
259301
| file://:0:0:0:0 | .value | semmle.label | .value |
260302
| file://:0:0:0:0 | .value2 | semmle.label | .value2 |
@@ -564,6 +606,12 @@ subpaths
564606
| SQLite.swift:156:21:156:43 | [...] | SQLite.swift:156:22:156:22 | mobilePhoneNumber | SQLite.swift:156:21:156:43 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | SQLite.swift:156:22:156:22 | mobilePhoneNumber | mobilePhoneNumber |
565607
| SQLite.swift:157:20:157:42 | [...] | SQLite.swift:157:21:157:21 | mobilePhoneNumber | SQLite.swift:157:20:157:42 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | SQLite.swift:157:21:157:21 | mobilePhoneNumber | mobilePhoneNumber |
566608
| SQLite.swift:158:23:158:45 | [...] | SQLite.swift:158:24:158:24 | mobilePhoneNumber | SQLite.swift:158:23:158:45 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | SQLite.swift:158:24:158:24 | mobilePhoneNumber | mobilePhoneNumber |
609+
| SQLite.swift:162:32:162:70 | [...] | SQLite.swift:162:53:162:53 | mobilePhoneNumber | SQLite.swift:162:32:162:70 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | SQLite.swift:162:53:162:53 | mobilePhoneNumber | mobilePhoneNumber |
610+
| SQLite.swift:163:28:163:66 | [...] | SQLite.swift:163:49:163:49 | mobilePhoneNumber | SQLite.swift:163:28:163:66 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | SQLite.swift:163:49:163:49 | mobilePhoneNumber | mobilePhoneNumber |
611+
| SQLite.swift:164:31:164:69 | [...] | SQLite.swift:164:52:164:52 | mobilePhoneNumber | SQLite.swift:164:31:164:69 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | SQLite.swift:164:52:164:52 | mobilePhoneNumber | mobilePhoneNumber |
612+
| SQLite.swift:167:21:167:59 | [...] | SQLite.swift:167:42:167:42 | mobilePhoneNumber | SQLite.swift:167:21:167:59 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | SQLite.swift:167:42:167:42 | mobilePhoneNumber | mobilePhoneNumber |
613+
| SQLite.swift:168:20:168:58 | [...] | SQLite.swift:168:41:168:41 | mobilePhoneNumber | SQLite.swift:168:20:168:58 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | SQLite.swift:168:41:168:41 | mobilePhoneNumber | mobilePhoneNumber |
614+
| SQLite.swift:169:23:169:61 | [...] | SQLite.swift:169:44:169:44 | mobilePhoneNumber | SQLite.swift:169:23:169:61 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | SQLite.swift:169:44:169:44 | mobilePhoneNumber | mobilePhoneNumber |
567615
| sqlite3_c_api.swift:46:27:46:27 | insertQuery | sqlite3_c_api.swift:42:69:42:69 | medicalNotes | sqlite3_c_api.swift:46:27:46:27 | insertQuery | This operation stores 'insertQuery' in a database. It may contain unencrypted sensitive data from $@. | sqlite3_c_api.swift:42:69:42:69 | medicalNotes | medicalNotes |
568616
| sqlite3_c_api.swift:47:27:47:27 | updateQuery | sqlite3_c_api.swift:43:49:43:49 | medicalNotes | sqlite3_c_api.swift:47:27:47:27 | updateQuery | This operation stores 'updateQuery' in a database. It may contain unencrypted sensitive data from $@. | sqlite3_c_api.swift:43:49:43:49 | medicalNotes | medicalNotes |
569617
| sqlite3_c_api.swift:58:36:58:36 | medicalNotes | sqlite3_c_api.swift:58:36:58:36 | medicalNotes | sqlite3_c_api.swift:58:36:58:36 | medicalNotes | This operation stores 'medicalNotes' in a database. It may contain unencrypted sensitive data from $@. | sqlite3_c_api.swift:58:36:58:36 | medicalNotes | medicalNotes |

swift/ql/test/query-tests/Security/CWE-311/SQLite.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -159,14 +159,14 @@ func test_sqlite_swift_api(db: Connection, id: Int, mobilePhoneNumber: String) t
159159

160160
let varQuery3 = "UPDATE CONTACTS SET NUMBER=$number WHERE ID=$id;"
161161

162-
_ = try db.prepare(varQuery3, ["id": id, "number": mobilePhoneNumber]).run() // BAD (sensitive data) [NOT DETECTED]
163-
_ = try db.run(varQuery3, ["id": id, "number": mobilePhoneNumber]) // BAD (sensitive data) [NOT DETECTED]
164-
_ = try db.scalar(varQuery3, ["id": id, "number": mobilePhoneNumber]) // BAD (sensitive data) [NOT DETECTED]
162+
_ = try db.prepare(varQuery3, ["id": id, "number": mobilePhoneNumber]).run() // BAD (sensitive data)
163+
_ = try db.run(varQuery3, ["id": id, "number": mobilePhoneNumber]) // BAD (sensitive data)
164+
_ = try db.scalar(varQuery3, ["id": id, "number": mobilePhoneNumber]) // BAD (sensitive data)
165165

166166
let stmt3 = try db.prepare(varQuery3) // GOOD
167-
_ = try stmt3.bind(["id": id, "number": mobilePhoneNumber]).run() // BAD (sensitive data) [NOT DETECTED]
168-
_ = try stmt3.run(["id": id, "number": mobilePhoneNumber]) // BAD (sensitive data) [NOT DETECTED]
169-
_ = try stmt3.scalar(["id": id, "number": mobilePhoneNumber]) // BAD (sensitive data) [NOT DETECTED]
167+
_ = try stmt3.bind(["id": id, "number": mobilePhoneNumber]).run() // BAD (sensitive data)
168+
_ = try stmt3.run(["id": id, "number": mobilePhoneNumber]) // BAD (sensitive data)
169+
_ = try stmt3.scalar(["id": id, "number": mobilePhoneNumber]) // BAD (sensitive data)
170170

171171
// --- higher level insert / update ---
172172

0 commit comments

Comments
 (0)