Skip to content

Commit 76ff593

Browse files
committed
Swift: Bring it all together into a query.
1 parent 7d78df2 commit 76ff593

File tree

3 files changed

+71
-55
lines changed

3 files changed

+71
-55
lines changed

swift/ql/src/queries/Security/CWE-089/SqlInjection.ql

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import swift
1414
import codeql.swift.dataflow.DataFlow
1515
import codeql.swift.dataflow.TaintTracking
16+
import codeql.swift.dataflow.FlowSources
1617
import DataFlow::PathGraph
1718

1819
/**
@@ -65,5 +66,18 @@ class SQLiteSwiftSqlSink extends SqlSink {
6566
}
6667
}
6768

68-
from SqlSink s
69-
select s
69+
/**
70+
* A taint configuration for tainted data that reaches an SQL sink.
71+
*/
72+
class SqlInjectionConfig extends TaintTracking::Configuration {
73+
SqlInjectionConfig() { this = "SqlInjectionConfig" }
74+
75+
override predicate isSource(DataFlow::Node node) { node instanceof RemoteFlowSource }
76+
77+
override predicate isSink(DataFlow::Node node) { node instanceof SqlSink }
78+
}
79+
80+
from SqlInjectionConfig config, DataFlow::PathNode sourceNode, DataFlow::PathNode sinkNode
81+
where config.hasFlowPath(sourceNode, sinkNode)
82+
select sinkNode.getNode(), sourceNode, sinkNode, "This SQL query depends on a $@.",
83+
sourceNode.getNode(), "user-provided value"
Lines changed: 46 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,50 @@
11
edges
2+
| SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | SQLite.swift:73:17:73:17 | unsafeQuery1 |
3+
| SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | SQLite.swift:74:17:74:17 | unsafeQuery2 |
4+
| SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | SQLite.swift:75:17:75:17 | unsafeQuery3 |
5+
| SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | SQLite.swift:83:29:83:29 | unsafeQuery3 |
6+
| SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | SQLite.swift:95:28:95:28 | remoteString |
7+
| SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | SQLite.swift:100:29:100:29 | unsafeQuery1 |
8+
| SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | SQLite.swift:103:29:103:29 | unsafeQuery1 |
9+
| SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | SQLite.swift:106:29:106:29 | unsafeQuery1 |
10+
| SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | SQLite.swift:109:9:109:9 | unsafeQuery1 |
11+
| SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | SQLite.swift:111:9:111:9 | unsafeQuery1 |
12+
| SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | SQLite.swift:113:9:113:9 | unsafeQuery1 |
13+
| SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | SQLite.swift:115:12:115:12 | unsafeQuery1 |
14+
| SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | SQLite.swift:117:12:117:12 | unsafeQuery1 |
15+
| SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | SQLite.swift:119:12:119:12 | unsafeQuery1 |
16+
| SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | SQLite.swift:132:16:132:16 | remoteString |
217
nodes
18+
| SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | semmle.label | call to init(contentsOf:) : |
19+
| SQLite.swift:73:17:73:17 | unsafeQuery1 | semmle.label | unsafeQuery1 |
20+
| SQLite.swift:74:17:74:17 | unsafeQuery2 | semmle.label | unsafeQuery2 |
21+
| SQLite.swift:75:17:75:17 | unsafeQuery3 | semmle.label | unsafeQuery3 |
22+
| SQLite.swift:83:29:83:29 | unsafeQuery3 | semmle.label | unsafeQuery3 |
23+
| SQLite.swift:95:28:95:28 | remoteString | semmle.label | remoteString |
24+
| SQLite.swift:100:29:100:29 | unsafeQuery1 | semmle.label | unsafeQuery1 |
25+
| SQLite.swift:103:29:103:29 | unsafeQuery1 | semmle.label | unsafeQuery1 |
26+
| SQLite.swift:106:29:106:29 | unsafeQuery1 | semmle.label | unsafeQuery1 |
27+
| SQLite.swift:109:9:109:9 | unsafeQuery1 | semmle.label | unsafeQuery1 |
28+
| SQLite.swift:111:9:111:9 | unsafeQuery1 | semmle.label | unsafeQuery1 |
29+
| SQLite.swift:113:9:113:9 | unsafeQuery1 | semmle.label | unsafeQuery1 |
30+
| SQLite.swift:115:12:115:12 | unsafeQuery1 | semmle.label | unsafeQuery1 |
31+
| SQLite.swift:117:12:117:12 | unsafeQuery1 | semmle.label | unsafeQuery1 |
32+
| SQLite.swift:119:12:119:12 | unsafeQuery1 | semmle.label | unsafeQuery1 |
33+
| SQLite.swift:132:16:132:16 | remoteString | semmle.label | remoteString |
334
subpaths
435
#select
5-
| SQLite.swift:29:86:29:86 | |
6-
| SQLite.swift:30:85:30:85 | |
7-
| SQLite.swift:31:93:31:93 | |
8-
| SQLite.swift:33:113:33:113 | |
9-
| SQLite.swift:34:112:34:112 | |
10-
| SQLite.swift:35:120:35:120 | |
11-
| SQLite.swift:45:113:45:113 | |
12-
| SQLite.swift:46:112:46:112 | |
13-
| SQLite.swift:47:120:47:120 | |
14-
| SQLite.swift:49:128:49:128 | |
15-
| SQLite.swift:50:127:50:127 | |
16-
| SQLite.swift:51:135:51:135 | |
17-
| SQLite.swift:73:17:73:17 | unsafeQuery1 |
18-
| SQLite.swift:74:17:74:17 | unsafeQuery2 |
19-
| SQLite.swift:75:17:75:17 | unsafeQuery3 |
20-
| SQLite.swift:76:17:76:17 | safeQuery1 |
21-
| SQLite.swift:77:17:77:17 | safeQuery2 |
22-
| SQLite.swift:83:29:83:29 | unsafeQuery3 |
23-
| SQLite.swift:86:29:86:29 | varQuery |
24-
| SQLite.swift:89:29:89:29 | varQuery |
25-
| SQLite.swift:92:28:92:28 | localString |
26-
| SQLite.swift:95:28:95:28 | remoteString |
27-
| SQLite.swift:100:29:100:29 | unsafeQuery1 |
28-
| SQLite.swift:103:29:103:29 | unsafeQuery1 |
29-
| SQLite.swift:106:29:106:29 | unsafeQuery1 |
30-
| SQLite.swift:109:9:109:9 | unsafeQuery1 |
31-
| SQLite.swift:111:9:111:9 | unsafeQuery1 |
32-
| SQLite.swift:113:9:113:9 | unsafeQuery1 |
33-
| SQLite.swift:115:12:115:12 | unsafeQuery1 |
34-
| SQLite.swift:117:12:117:12 | unsafeQuery1 |
35-
| SQLite.swift:119:12:119:12 | unsafeQuery1 |
36-
| SQLite.swift:121:29:121:29 | varQuery |
37-
| SQLite.swift:132:16:132:16 | remoteString |
38-
| sqlite3_c_api.swift:133:33:133:33 | (UnsafePointer<CChar>) ... |
39-
| sqlite3_c_api.swift:134:33:134:33 | (UnsafePointer<CChar>) ... |
40-
| sqlite3_c_api.swift:135:33:135:33 | (UnsafePointer<CChar>) ... |
41-
| sqlite3_c_api.swift:136:33:136:33 | (UnsafePointer<CChar>) ... |
42-
| sqlite3_c_api.swift:137:33:137:33 | (UnsafePointer<CChar>) ... |
43-
| sqlite3_c_api.swift:145:26:145:26 | (UnsafePointer<CChar>) ... |
44-
| sqlite3_c_api.swift:153:26:153:26 | (UnsafePointer<CChar>) ... |
45-
| sqlite3_c_api.swift:163:26:163:26 | (UnsafePointer<CChar>) ... |
46-
| sqlite3_c_api.swift:175:29:175:29 | (UnsafePointer<CChar>) ... |
47-
| sqlite3_c_api.swift:194:28:194:28 | buffer |
48-
| sqlite3_c_api.swift:202:31:202:31 | buffer |
36+
| SQLite.swift:73:17:73:17 | unsafeQuery1 | SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | SQLite.swift:73:17:73:17 | unsafeQuery1 | This SQL query depends on a $@. | SQLite.swift:62:26:62:80 | call to init(contentsOf:) | user-provided value |
37+
| SQLite.swift:74:17:74:17 | unsafeQuery2 | SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | SQLite.swift:74:17:74:17 | unsafeQuery2 | This SQL query depends on a $@. | SQLite.swift:62:26:62:80 | call to init(contentsOf:) | user-provided value |
38+
| SQLite.swift:75:17:75:17 | unsafeQuery3 | SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | SQLite.swift:75:17:75:17 | unsafeQuery3 | This SQL query depends on a $@. | SQLite.swift:62:26:62:80 | call to init(contentsOf:) | user-provided value |
39+
| SQLite.swift:83:29:83:29 | unsafeQuery3 | SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | SQLite.swift:83:29:83:29 | unsafeQuery3 | This SQL query depends on a $@. | SQLite.swift:62:26:62:80 | call to init(contentsOf:) | user-provided value |
40+
| SQLite.swift:95:28:95:28 | remoteString | SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | SQLite.swift:95:28:95:28 | remoteString | This SQL query depends on a $@. | SQLite.swift:62:26:62:80 | call to init(contentsOf:) | user-provided value |
41+
| SQLite.swift:100:29:100:29 | unsafeQuery1 | SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | SQLite.swift:100:29:100:29 | unsafeQuery1 | This SQL query depends on a $@. | SQLite.swift:62:26:62:80 | call to init(contentsOf:) | user-provided value |
42+
| SQLite.swift:103:29:103:29 | unsafeQuery1 | SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | SQLite.swift:103:29:103:29 | unsafeQuery1 | This SQL query depends on a $@. | SQLite.swift:62:26:62:80 | call to init(contentsOf:) | user-provided value |
43+
| SQLite.swift:106:29:106:29 | unsafeQuery1 | SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | SQLite.swift:106:29:106:29 | unsafeQuery1 | This SQL query depends on a $@. | SQLite.swift:62:26:62:80 | call to init(contentsOf:) | user-provided value |
44+
| SQLite.swift:109:9:109:9 | unsafeQuery1 | SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | SQLite.swift:109:9:109:9 | unsafeQuery1 | This SQL query depends on a $@. | SQLite.swift:62:26:62:80 | call to init(contentsOf:) | user-provided value |
45+
| SQLite.swift:111:9:111:9 | unsafeQuery1 | SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | SQLite.swift:111:9:111:9 | unsafeQuery1 | This SQL query depends on a $@. | SQLite.swift:62:26:62:80 | call to init(contentsOf:) | user-provided value |
46+
| SQLite.swift:113:9:113:9 | unsafeQuery1 | SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | SQLite.swift:113:9:113:9 | unsafeQuery1 | This SQL query depends on a $@. | SQLite.swift:62:26:62:80 | call to init(contentsOf:) | user-provided value |
47+
| SQLite.swift:115:12:115:12 | unsafeQuery1 | SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | SQLite.swift:115:12:115:12 | unsafeQuery1 | This SQL query depends on a $@. | SQLite.swift:62:26:62:80 | call to init(contentsOf:) | user-provided value |
48+
| SQLite.swift:117:12:117:12 | unsafeQuery1 | SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | SQLite.swift:117:12:117:12 | unsafeQuery1 | This SQL query depends on a $@. | SQLite.swift:62:26:62:80 | call to init(contentsOf:) | user-provided value |
49+
| SQLite.swift:119:12:119:12 | unsafeQuery1 | SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | SQLite.swift:119:12:119:12 | unsafeQuery1 | This SQL query depends on a $@. | SQLite.swift:62:26:62:80 | call to init(contentsOf:) | user-provided value |
50+
| SQLite.swift:132:16:132:16 | remoteString | SQLite.swift:62:26:62:80 | call to init(contentsOf:) : | SQLite.swift:132:16:132:16 | remoteString | This SQL query depends on a $@. | SQLite.swift:62:26:62:80 | call to init(contentsOf:) | user-provided value |

swift/ql/test/query-tests/Security/CWE-089/sqlite3_c_api.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,9 @@ func test_sqlite3_c_api(db: OpaquePointer?, buffer: UnsafeMutablePointer<UInt8>)
130130

131131
// --- exec ---
132132

133-
let result1 = sqlite3_exec(db, unsafeQuery1, nil, nil, nil) // BAD
134-
let result2 = sqlite3_exec(db, unsafeQuery2, nil, nil, nil) // BAD
135-
let result3 = sqlite3_exec(db, unsafeQuery3, nil, nil, nil) // BAD
133+
let result1 = sqlite3_exec(db, unsafeQuery1, nil, nil, nil) // BAD [NOT DETECTED]
134+
let result2 = sqlite3_exec(db, unsafeQuery2, nil, nil, nil) // BAD [NOT DETECTED]
135+
let result3 = sqlite3_exec(db, unsafeQuery3, nil, nil, nil) // BAD [NOT DETECTED]
136136
let result4 = sqlite3_exec(db, safeQuery1, nil, nil, nil) // GOOD
137137
let result5 = sqlite3_exec(db, safeQuery2, nil, nil, nil) // GOOD
138138

@@ -142,7 +142,7 @@ func test_sqlite3_c_api(db: OpaquePointer?, buffer: UnsafeMutablePointer<UInt8>)
142142

143143
var stmt1: OpaquePointer?
144144

145-
if (sqlite3_prepare(db, unsafeQuery3, -1, &stmt1, nil) == SQLITE_OK) { // BAD
145+
if (sqlite3_prepare(db, unsafeQuery3, -1, &stmt1, nil) == SQLITE_OK) { // BAD [NOT DETECTED]
146146
let result = sqlite3_step(stmt1)
147147
// ...
148148
}
@@ -172,15 +172,15 @@ func test_sqlite3_c_api(db: OpaquePointer?, buffer: UnsafeMutablePointer<UInt8>)
172172

173173
var stmt4: OpaquePointer?
174174

175-
if (sqlite3_prepare_v2(db, unsafeQuery3, -1, &stmt4, nil) == SQLITE_OK) { // BAD
175+
if (sqlite3_prepare_v2(db, unsafeQuery3, -1, &stmt4, nil) == SQLITE_OK) { // BAD [NOT DETECTED]
176176
let result = sqlite3_step(stmt4)
177177
// ...
178178
}
179179
sqlite3_finalize(stmt4)
180180

181181
var stmt5: OpaquePointer?
182182

183-
if (sqlite3_prepare_v3(db, unsafeQuery3, -1, 0, &stmt5, nil) == SQLITE_OK) { // BAD
183+
if (sqlite3_prepare_v3(db, unsafeQuery3, -1, 0, &stmt5, nil) == SQLITE_OK) { // BAD [NOT DETECTED]
184184
let result = sqlite3_step(stmt5)
185185
// ...
186186
}
@@ -191,23 +191,23 @@ func test_sqlite3_c_api(db: OpaquePointer?, buffer: UnsafeMutablePointer<UInt8>)
191191

192192
var stmt6: OpaquePointer?
193193

194-
if (sqlite3_prepare16(db, buffer, Int32(data.count), &stmt6, nil) == SQLITE_OK) { // BAD
194+
if (sqlite3_prepare16(db, buffer, Int32(data.count), &stmt6, nil) == SQLITE_OK) { // BAD [NOT DETECTED]
195195
let result = sqlite3_step(stmt6)
196196
// ...
197197
}
198198
sqlite3_finalize(stmt6)
199199

200200
var stmt7: OpaquePointer?
201201

202-
if (sqlite3_prepare16_v2(db, buffer, Int32(data.count), &stmt7, nil) == SQLITE_OK) { // BAD
202+
if (sqlite3_prepare16_v2(db, buffer, Int32(data.count), &stmt7, nil) == SQLITE_OK) { // BAD [NOT DETECTED]
203203
let result = sqlite3_step(stmt7)
204204
// ...
205205
}
206206
sqlite3_finalize(stmt7)
207207

208208
var stmt8: OpaquePointer?
209209

210-
if (sqlite3_prepare16_v3(db, buffer, Int32(data.count), 0, &stmt8, nil) == SQLITE_OK) { // BAD
210+
if (sqlite3_prepare16_v3(db, buffer, Int32(data.count), 0, &stmt8, nil) == SQLITE_OK) { // BAD [NOT DETECTED]
211211
let result = sqlite3_step(stmt8)
212212
// ...
213213
}

0 commit comments

Comments
 (0)