Skip to content

Commit f19c6f3

Browse files
committed
Swift: Add imprecise append/insert models.
1 parent 6e5c285 commit f19c6f3

File tree

3 files changed

+58
-19
lines changed

3 files changed

+58
-19
lines changed

swift/ql/lib/codeql/swift/frameworks/Heuristic.qll

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,42 @@ private class InitializerFromDataStep extends AdditionalTaintStep {
7070
)
7171
}
7272
}
73+
74+
/**
75+
* An imprecise flow step for an `append`, `insert` or similar function. For
76+
* example:
77+
* ```
78+
* mc.append(taintedObj)
79+
* mc.insert(taintedObj, at: 0)
80+
* ```
81+
*/
82+
private class AppendCallStep extends AdditionalTaintStep {
83+
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
84+
exists(CallExpr ce, Argument arg |
85+
ce.getAnArgument() = arg and
86+
ce.getStaticTarget().(Function).getShortName() = ["append", "insert"] and
87+
arg.getLabel() = ["", "contentsOf"] and
88+
node1.asExpr() = arg.getExpr() and
89+
node2.asExpr() = ce.getQualifier()
90+
)
91+
}
92+
}
93+
94+
/**
95+
* An imprecise flow step for an `appending` or similar function. For
96+
* example:
97+
* ```
98+
* let mc2 = mc.appending(taintedObj)
99+
* ```
100+
*/
101+
private class AppendingCallStep extends AdditionalTaintStep {
102+
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
103+
exists(CallExpr ce, Argument arg |
104+
ce.getAnArgument() = arg and
105+
ce.getStaticTarget().(Function).getShortName() = ["appending", "inserting"] and
106+
arg.getLabel() = ["", "contentsOf"] and
107+
node1.asExpr() = arg.getExpr() and
108+
node2.asExpr() = ce
109+
)
110+
}
111+
}

swift/ql/test/library-tests/dataflow/taint/libraries/array.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func testArray() {
3333
arr4.insert(contentsOf: arrClean, at: 0)
3434
sink(arg: arr4[0])
3535
arr4.insert(contentsOf: arr3, at: 0)
36-
sink(arg: arr4[0]) // $ MISSING: tainted=int3
36+
sink(arg: arr4[0]) // $ tainted=int3
3737

3838
var arr5 = Array<Int>()
3939
arr5.insert(contentsOf: 1...10, at: 0)

swift/ql/test/library-tests/dataflow/taint/libraries/custom.swift

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -54,50 +54,50 @@ func testCustom() {
5454
sink(arg: mc1)
5555
sink(arg: mc1[0])
5656
mc1.append(source("data3"))
57-
sink(arg: mc1) // $ MISSING: tainted=data3
58-
sink(arg: mc1[0]) // $ MISSING: tainted=data3
57+
sink(arg: mc1) // $ tainted=data3
58+
sink(arg: mc1[0]) // $ tainted=data3
5959

6060
var mc2 = MyContainer()
6161
mc2.insert(Data(0), at: 0)
6262
sink(arg: mc2)
6363
sink(arg: mc2[0])
6464
mc2.insert(source("data4"), at: 0)
65-
sink(arg: mc2) // $ MISSING: tainted=data4
66-
sink(arg: mc2[0]) // $ MISSING: tainted=data4
65+
sink(arg: mc2) // $ tainted=data4
66+
sink(arg: mc2[0]) // $ tainted=data4
6767

6868
var mc3 = MyContainer()
6969
mc3.append(contentsOf: clean)
7070
sink(arg: mc3)
7171
sink(arg: mc3[0])
7272
mc3.append(contentsOf: tainted)
73-
sink(arg: mc3) // $ MISSING: tainted=data1
74-
sink(arg: mc3[0]) // $ MISSING: tainted=data1
73+
sink(arg: mc3) // $ tainted=data1
74+
sink(arg: mc3[0]) // $ tainted=data1
7575

7676
var mc4 = MyContainer()
7777
mc4.insert(contentsOf: clean, at: 0)
7878
sink(arg: mc4)
7979
sink(arg: mc4[0])
8080
mc4.insert(contentsOf: tainted, at: 0)
81-
sink(arg: mc4) // $ MISSING: tainted=data1
82-
sink(arg: mc4[0]) // $ MISSING: tainted=data1
81+
sink(arg: mc4) // $ tainted=data1
82+
sink(arg: mc4[0]) // $ tainted=data1
8383

8484
let mc5 = MyContainer()
8585
sink(arg: mc5.appending(Data(0)))
8686
sink(arg: mc5.appending(Data(0))[0])
87-
sink(arg: mc5.appending(source("data5"))) // $ MISSING: tainted=data5
88-
sink(arg: mc5.appending(source("data6"))[0]) // $ MISSING: tainted=data6
87+
sink(arg: mc5.appending(source("data5"))) // $ tainted=data5
88+
sink(arg: mc5.appending(source("data6"))[0]) // $ tainted=data6
8989
sink(arg: mc5.inserting(Data(0), at: 0))
9090
sink(arg: mc5.inserting(Data(0), at: 0)[0])
91-
sink(arg: mc5.inserting(source("data7"), at: 0)) // $ MISSING: tainted=data7
92-
sink(arg: mc5.inserting(source("data8"), at: 0)[0]) // $ MISSING: tainted=data8
91+
sink(arg: mc5.inserting(source("data7"), at: 0)) // $ tainted=data7
92+
sink(arg: mc5.inserting(source("data8"), at: 0)[0]) // $ tainted=data8
9393
sink(arg: mc5.appending(contentsOf: clean))
9494
sink(arg: mc5.appending(contentsOf: clean)[0])
95-
sink(arg: mc5.appending(contentsOf: tainted)) // $ MISSING: tainted=data1
96-
sink(arg: mc5.appending(contentsOf: tainted)[0]) // $ MISSING: tainted=data1
95+
sink(arg: mc5.appending(contentsOf: tainted)) // $ tainted=data1
96+
sink(arg: mc5.appending(contentsOf: tainted)[0]) // $ tainted=data1
9797
sink(arg: mc5.inserting(contentsOf: clean, at: 0))
9898
sink(arg: mc5.inserting(contentsOf: clean, at: 0)[0])
99-
sink(arg: mc5.inserting(contentsOf: tainted, at: 0)) // $ MISSING: tainted=data1
100-
sink(arg: mc5.inserting(contentsOf: tainted, at: 0)[0]) // $ MISSING: tainted=data1
99+
sink(arg: mc5.inserting(contentsOf: tainted, at: 0)) // $ tainted=data1
100+
sink(arg: mc5.inserting(contentsOf: tainted, at: 0)[0]) // $ tainted=data1
101101
sink(arg: mc5)
102102

103103
let taintedString = sourceString("data9")
@@ -106,8 +106,8 @@ func testCustom() {
106106
sink(arg: mc6)
107107
sink(arg: mc6[0])
108108
mc6.append(taintedString)
109-
sink(arg: mc6) // $ MISSING: tainted=data9
110-
sink(arg: mc6[0]) // $ MISSING: tainted=data9
109+
sink(arg: mc6) // $ tainted=data9
110+
sink(arg: mc6[0]) // $ tainted=data9
111111

112112
let taintedArray = [source("data10")]
113113
var mc7 = MyContainer()

0 commit comments

Comments
 (0)