Skip to content

Commit 664dc01

Browse files
committed
Swift: Add closure function models.
1 parent 49d1556 commit 664dc01

File tree

5 files changed

+65
-21
lines changed

5 files changed

+65
-21
lines changed

swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Array.qll

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,32 @@ class ArrayType extends Type {
1313
}
1414

1515
/**
16-
* A model for `Array` and related class members that permit data flow.
16+
* A model for `Array` and related Swift class members that permit taint flow.
1717
*/
1818
private class ArraySummaries extends SummaryModelCsv {
1919
override predicate row(string row) {
2020
row =
2121
[
2222
";Array;true;insert(_:at:);;;Argument[0];Argument[-1].ArrayElement;value",
23-
";Array;true;insert(_:at:);;;Argument[1];Argument[-1];taint"
23+
";Array;true;insert(_:at:);;;Argument[1];Argument[-1];taint",
24+
";Array;true;withUnsafeBufferPointer(_:);;;Argument[-1];Argument[0].Parameter[0];taint",
25+
";Array;true;withUnsafeBufferPointer(_:);;;Argument[0].ReturnValue;ReturnValue;value",
26+
";Array;true;withUnsafeMutableBufferPointer(_:);;;Argument[-1];Argument[0].Parameter[0];taint",
27+
";Array;true;withUnsafeMutableBufferPointer(_:);;;Argument[0].Parameter[0];Argument[-1];taint",
28+
";Array;true;withUnsafeMutableBufferPointer(_:);;;Argument[0].ReturnValue;ReturnValue;value",
29+
";Array;true;withUnsafeMutableBytes(_:);;;Argument[-1];Argument[0].Parameter[0];taint",
30+
";Array;true;withUnsafeMutableBytes(_:);;;Argument[0].Parameter[0];Argument[-1];taint",
31+
";Array;true;withUnsafeMutableBytes(_:);;;Argument[0].ReturnValue;ReturnValue;value",
32+
";ContiguousArray;true;withUnsafeBufferPointer(_:);;;Argument[-1];Argument[0].Parameter[0];taint",
33+
";ContiguousArray;true;withUnsafeBufferPointer(_:);;;Argument[0].ReturnValue;ReturnValue;value",
34+
";ContiguousArray;true;withUnsafeMutableBufferPointer(_:);;;Argument[-1];Argument[0].Parameter[0];taint",
35+
";ContiguousArray;true;withUnsafeMutableBufferPointer(_:);;;Argument[0].Parameter[0];Argument[-1];taint",
36+
";ContiguousArray;true;withUnsafeMutableBufferPointer(_:);;;Argument[0].ReturnValue;ReturnValue;value",
37+
";ContiguousArray;true;withUnsafeMutableBytes(_:);;;Argument[-1];Argument[0].Parameter[0];taint",
38+
";ContiguousArray;true;withUnsafeMutableBytes(_:);;;Argument[0].Parameter[0];Argument[-1];taint",
39+
";ContiguousArray;true;withUnsafeMutableBytes(_:);;;Argument[0].ReturnValue;ReturnValue;value",
40+
";ContiguousBytes;true;withUnsafeBytes(_:);;;Argument[-1];Argument[0].Parameter[0];taint",
41+
";ContiguousBytes;true;withUnsafeBytes(_:);;;Argument[0].ReturnValue;ReturnValue;value",
2442
]
2543
}
2644
}

swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Collection.qll

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ private import codeql.swift.dataflow.ExternalFlow
88
private import codeql.swift.dataflow.FlowSteps
99

1010
/**
11-
* A model for `Collection` members that permit taint flow.
11+
* A model for `Collection` and related Swift class members that permit taint flow.
1212
*/
1313
private class CollectionSummaries extends SummaryModelCsv {
1414
override predicate row(string row) {
@@ -35,6 +35,9 @@ private class CollectionSummaries extends SummaryModelCsv {
3535
";BidirectionalCollection;true;joined(separator:);;;Argument[-1..0];ReturnValue;taint",
3636
";BidirectionalCollection;true;last(where:);;;Argument[-1];ReturnValue;taint",
3737
";BidirectionalCollection;true;popLast();;;Argument[-1];ReturnValue;taint",
38+
";MutableCollection;true;withContiguousMutableStorageIfAvailable(_:);;;Argument[-1];Argument[0].Parameter[0];taint",
39+
";MutableCollection;true;withContiguousMutableStorageIfAvailable(_:);;;Argument[0].Parameter[0];Argument[-1];taint",
40+
";MutableCollection;true;withContiguousMutableStorageIfAvailable(_:);;;Argument[0].ReturnValue;ReturnValue.OptionalSome;value",
3841
]
3942
}
4043
}

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

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func taintThroughClosurePointer() {
3434
sink(arg: ptr2[0]) // $ MISSING: tainted=28
3535
return source()
3636
})
37-
sink(arg: return2) // $ MISSING: tainted=35
37+
sink(arg: return2) // $ tainted=35
3838
}
3939

4040
func taintThroughMutablePointer() {
@@ -45,14 +45,14 @@ func taintThroughMutablePointer() {
4545
let return1 = myArray1.withUnsafeMutableBufferPointer({
4646
buffer in
4747
buffer.update(repeating: source())
48-
sink(arg: buffer) // $ tainted=47
48+
sink(arg: buffer) // $ SPURIOUS: tainted=47
4949
sink(arg: buffer[0]) // $ tainted=47
5050
sink(arg: buffer.baseAddress!.pointee) // $ MISSING: tainted=47
5151
return source()
5252
})
53-
sink(arg: return1) // $ MISSING: tainted=47
54-
sink(arg: myArray1)
55-
sink(arg: myArray1[0]) // $ MISSING: tainted=47
53+
sink(arg: return1) // $ tainted=51
54+
sink(arg: myArray1) // $ tainted=47
55+
sink(arg: myArray1[0]) // $ tainted=47
5656

5757
// ---
5858

@@ -68,7 +68,7 @@ func taintThroughMutablePointer() {
6868
sink(arg: buffer.baseAddress!.pointee) // $ MISSING: tainted=65
6969
return source()
7070
})
71-
sink(arg: return2) // $ MISSING: tainted=65
71+
sink(arg: return2) // $ tainted=69
7272
sink(arg: myArray2)
7373
sink(arg: myArray2[0]) // $ MISSING: tainted=65
7474

@@ -81,13 +81,13 @@ func taintThroughMutablePointer() {
8181
let return3 = myArray3.withContiguousMutableStorageIfAvailable({
8282
ptr in
8383
ptr.update(repeating: source())
84-
sink(arg: ptr) // $ tainted=83
84+
sink(arg: ptr) // $ SPURIOUS: tainted=83
8585
sink(arg: ptr[0]) // $ tainted=83
8686
return source()
8787
})
88-
sink(arg: return3!) // $ MISSING: tainted=83
89-
sink(arg: myArray3)
90-
sink(arg: myArray3[0]) // $ MISSING: tainted=83
88+
sink(arg: return3!) // $ tainted=86
89+
sink(arg: myArray3) // $ SPURIOUS: tainted=83
90+
sink(arg: myArray3[0]) // $ tainted=83
9191

9292
// ---
9393

@@ -113,7 +113,7 @@ func taintThroughMutablePointer() {
113113
sink(arg: return5) // $ MISSING: tainted=111
114114
return source()
115115
})
116-
sink(arg: return4) // $ MISSING: tainted=114
116+
sink(arg: return4) // $ tainted=114
117117
sink(arg: myArray4)
118118
sink(arg: myArray4[0]) // $ MISSING: tainted=97
119119
sink(arg: myArray5)
@@ -133,9 +133,9 @@ func taintThroughMutablePointer() {
133133
sink(arg: ptr[0]) // $ tainted=131
134134
return source()
135135
})
136-
sink(arg: return6!) // $ MISSING: tainted=134
137-
sink(arg: myMutableBuffer)
138-
sink(arg: myMutableBuffer[0]) // $ MISSING: tainted=131
136+
sink(arg: return6!) // $ tainted=134
137+
sink(arg: myMutableBuffer) // $ SPURIOUS: tainted=131
138+
sink(arg: myMutableBuffer[0]) // $ tainted=131
139139
}
140140

141141
func taintCollections(array: inout Array<Int>, contiguousArray: inout ContiguousArray<Int>, dictionary: inout Dictionary<Int, Int>) {

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ func taintFromUInt8Array() {
480480
})
481481
try! taintedUInt8Values.withUnsafeBufferPointer({
482482
(buffer: UnsafeBufferPointer<UInt8>) throws in
483-
sink(arg: buffer) // $ MISSING: tainted=450
483+
sink(arg: buffer) // $ tainted=450
484484
sink(arg: buffer.baseAddress!) // $ MISSING: tainted=450
485485
sink(arg: String(cString: buffer.baseAddress!)) // $ MISSING: tainted=450
486486
})
@@ -493,7 +493,7 @@ func taintFromUInt8Array() {
493493
})
494494
try! taintedUInt8Values.withUnsafeMutableBytes({
495495
(buffer: UnsafeMutableRawBufferPointer) throws in
496-
sink(arg: buffer) // $ MISSING: tainted=450
496+
sink(arg: buffer) // $ tainted=450
497497
sink(arg: buffer.baseAddress!) // $ MISSING: tainted=450
498498
sink(arg: String(bytesNoCopy: buffer.baseAddress!, length: buffer.count, encoding: String.Encoding.utf8, freeWhenDone: false)!) // $ MISSING: tainted=450
499499
})
@@ -515,7 +515,7 @@ func taintThroughCCharArray() {
515515
})
516516
taintedCCharValues.withUnsafeBufferPointer({
517517
ptr in
518-
sink(arg: ptr) // $ MISSING: tainted=506
518+
sink(arg: ptr) // $ tainted=506
519519
sink(arg: ptr.baseAddress!) // $ MISSING: tainted=506
520520
sink(arg: String(utf8String: ptr.baseAddress!)!) // $ MISSING: tainted=506
521521
sink(arg: String(validatingUTF8: ptr.baseAddress!)!) // $ MISSING: tainted=506
@@ -541,7 +541,7 @@ func taintThroughUnicharArray() {
541541
})
542542
taintedUnicharValues.withUnsafeBufferPointer({
543543
ptr in
544-
sink(arg: ptr) // $ MISSING: tainted=533
544+
sink(arg: ptr) // $ tainted=533
545545
sink(arg: ptr.baseAddress!) // $ MISSING: tainted=533
546546
sink(arg: String(utf16CodeUnits: ptr.baseAddress!, count: ptr.count)) // $ MISSING: tainted=533
547547
sink(arg: String(utf16CodeUnitsNoCopy: ptr.baseAddress!, count: ptr.count, freeWhenDone: false)) // $ MISSING: tainted=533

swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,28 @@ edges
1010
| UnsafeJsEval.swift:204:7:204:66 | try! ... | UnsafeJsEval.swift:276:13:276:13 | string |
1111
| UnsafeJsEval.swift:204:7:204:66 | try! ... | UnsafeJsEval.swift:279:13:279:13 | string |
1212
| UnsafeJsEval.swift:204:7:204:66 | try! ... | UnsafeJsEval.swift:285:13:285:13 | string |
13+
| UnsafeJsEval.swift:204:7:204:66 | try! ... | UnsafeJsEval.swift:299:13:299:13 | string |
1314
| UnsafeJsEval.swift:204:12:204:66 | call to String.init(contentsOf:) | UnsafeJsEval.swift:204:7:204:66 | try! ... |
1415
| UnsafeJsEval.swift:205:7:205:7 | remoteString | UnsafeJsEval.swift:265:13:265:13 | string |
1516
| UnsafeJsEval.swift:205:7:205:7 | remoteString | UnsafeJsEval.swift:268:13:268:13 | string |
1617
| UnsafeJsEval.swift:205:7:205:7 | remoteString | UnsafeJsEval.swift:276:13:276:13 | string |
1718
| UnsafeJsEval.swift:205:7:205:7 | remoteString | UnsafeJsEval.swift:279:13:279:13 | string |
1819
| UnsafeJsEval.swift:205:7:205:7 | remoteString | UnsafeJsEval.swift:285:13:285:13 | string |
20+
| UnsafeJsEval.swift:205:7:205:7 | remoteString | UnsafeJsEval.swift:299:13:299:13 | string |
1921
| UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... | UnsafeJsEval.swift:265:13:265:13 | string |
2022
| UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... | UnsafeJsEval.swift:268:13:268:13 | string |
2123
| UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... | UnsafeJsEval.swift:276:13:276:13 | string |
2224
| UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... | UnsafeJsEval.swift:279:13:279:13 | string |
2325
| UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... | UnsafeJsEval.swift:285:13:285:13 | string |
26+
| UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... | UnsafeJsEval.swift:299:13:299:13 | string |
2427
| UnsafeJsEval.swift:211:19:211:41 | call to Data.init(_:) | UnsafeJsEval.swift:214:24:214:24 | remoteData |
2528
| UnsafeJsEval.swift:211:24:211:37 | .utf8 | UnsafeJsEval.swift:211:19:211:41 | call to Data.init(_:) |
2629
| UnsafeJsEval.swift:214:7:214:49 | call to String.init(decoding:as:) | UnsafeJsEval.swift:265:13:265:13 | string |
2730
| UnsafeJsEval.swift:214:7:214:49 | call to String.init(decoding:as:) | UnsafeJsEval.swift:268:13:268:13 | string |
2831
| UnsafeJsEval.swift:214:7:214:49 | call to String.init(decoding:as:) | UnsafeJsEval.swift:276:13:276:13 | string |
2932
| UnsafeJsEval.swift:214:7:214:49 | call to String.init(decoding:as:) | UnsafeJsEval.swift:279:13:279:13 | string |
3033
| UnsafeJsEval.swift:214:7:214:49 | call to String.init(decoding:as:) | UnsafeJsEval.swift:285:13:285:13 | string |
34+
| UnsafeJsEval.swift:214:7:214:49 | call to String.init(decoding:as:) | UnsafeJsEval.swift:299:13:299:13 | string |
3135
| UnsafeJsEval.swift:214:24:214:24 | remoteData | UnsafeJsEval.swift:214:7:214:49 | call to String.init(decoding:as:) |
3236
| UnsafeJsEval.swift:265:13:265:13 | string | UnsafeJsEval.swift:266:43:266:43 | string |
3337
| UnsafeJsEval.swift:266:43:266:43 | string | UnsafeJsEval.swift:266:22:266:107 | call to WKUserScript.init(source:injectionTime:forMainFrameOnly:) |
@@ -43,6 +47,14 @@ edges
4347
| UnsafeJsEval.swift:287:31:287:97 | call to JSStringCreateWithCharacters(_:_:) | UnsafeJsEval.swift:287:16:287:98 | call to JSStringRetain(_:) |
4448
| UnsafeJsEval.swift:287:60:287:60 | stringBytes | UnsafeJsEval.swift:287:60:287:72 | .baseAddress |
4549
| UnsafeJsEval.swift:287:60:287:72 | .baseAddress | UnsafeJsEval.swift:287:31:287:97 | call to JSStringCreateWithCharacters(_:_:) |
50+
| UnsafeJsEval.swift:299:13:299:13 | string | UnsafeJsEval.swift:300:3:300:10 | .utf8CString |
51+
| UnsafeJsEval.swift:300:3:300:10 | .utf8CString | UnsafeJsEval.swift:300:48:300:48 | stringBytes |
52+
| UnsafeJsEval.swift:300:48:300:48 | stringBytes | UnsafeJsEval.swift:301:61:301:61 | stringBytes |
53+
| UnsafeJsEval.swift:301:16:301:85 | call to JSStringRetain(_:) | UnsafeJsEval.swift:305:17:305:17 | jsstr |
54+
| UnsafeJsEval.swift:301:31:301:84 | call to JSStringCreateWithUTF8CString(_:) | UnsafeJsEval.swift:124:21:124:42 | string |
55+
| UnsafeJsEval.swift:301:31:301:84 | call to JSStringCreateWithUTF8CString(_:) | UnsafeJsEval.swift:301:16:301:85 | call to JSStringRetain(_:) |
56+
| UnsafeJsEval.swift:301:61:301:61 | stringBytes | UnsafeJsEval.swift:301:61:301:73 | .baseAddress |
57+
| UnsafeJsEval.swift:301:61:301:73 | .baseAddress | UnsafeJsEval.swift:301:31:301:84 | call to JSStringCreateWithUTF8CString(_:) |
4658
| UnsafeJsEval.swift:318:24:318:87 | call to String.init(contentsOf:) | UnsafeJsEval.swift:320:44:320:74 | ... .+(_:_:) ... |
4759
nodes
4860
| UnsafeJsEval.swift:124:21:124:42 | string | semmle.label | string |
@@ -76,10 +88,19 @@ nodes
7688
| UnsafeJsEval.swift:287:60:287:60 | stringBytes | semmle.label | stringBytes |
7789
| UnsafeJsEval.swift:287:60:287:72 | .baseAddress | semmle.label | .baseAddress |
7890
| UnsafeJsEval.swift:291:17:291:17 | jsstr | semmle.label | jsstr |
91+
| UnsafeJsEval.swift:299:13:299:13 | string | semmle.label | string |
92+
| UnsafeJsEval.swift:300:3:300:10 | .utf8CString | semmle.label | .utf8CString |
93+
| UnsafeJsEval.swift:300:48:300:48 | stringBytes | semmle.label | stringBytes |
94+
| UnsafeJsEval.swift:301:16:301:85 | call to JSStringRetain(_:) | semmle.label | call to JSStringRetain(_:) |
95+
| UnsafeJsEval.swift:301:31:301:84 | call to JSStringCreateWithUTF8CString(_:) | semmle.label | call to JSStringCreateWithUTF8CString(_:) |
96+
| UnsafeJsEval.swift:301:61:301:61 | stringBytes | semmle.label | stringBytes |
97+
| UnsafeJsEval.swift:301:61:301:73 | .baseAddress | semmle.label | .baseAddress |
98+
| UnsafeJsEval.swift:305:17:305:17 | jsstr | semmle.label | jsstr |
7999
| UnsafeJsEval.swift:318:24:318:87 | call to String.init(contentsOf:) | semmle.label | call to String.init(contentsOf:) |
80100
| UnsafeJsEval.swift:320:44:320:74 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... |
81101
subpaths
82102
| UnsafeJsEval.swift:287:31:287:97 | call to JSStringCreateWithCharacters(_:_:) | UnsafeJsEval.swift:124:21:124:42 | string | UnsafeJsEval.swift:124:70:124:70 | string | UnsafeJsEval.swift:287:16:287:98 | call to JSStringRetain(_:) |
103+
| UnsafeJsEval.swift:301:31:301:84 | call to JSStringCreateWithUTF8CString(_:) | UnsafeJsEval.swift:124:21:124:42 | string | UnsafeJsEval.swift:124:70:124:70 | string | UnsafeJsEval.swift:301:16:301:85 | call to JSStringRetain(_:) |
83104
#select
84105
| UnsafeJsEval.swift:266:22:266:107 | call to WKUserScript.init(source:injectionTime:forMainFrameOnly:) | UnsafeJsEval.swift:165:14:165:37 | call to String.init(contentsOf:) | UnsafeJsEval.swift:266:22:266:107 | call to WKUserScript.init(source:injectionTime:forMainFrameOnly:) | Evaluation of uncontrolled JavaScript from a remote source. |
85106
| UnsafeJsEval.swift:266:22:266:107 | call to WKUserScript.init(source:injectionTime:forMainFrameOnly:) | UnsafeJsEval.swift:204:12:204:66 | call to String.init(contentsOf:) | UnsafeJsEval.swift:266:22:266:107 | call to WKUserScript.init(source:injectionTime:forMainFrameOnly:) | Evaluation of uncontrolled JavaScript from a remote source. |
@@ -91,4 +112,6 @@ subpaths
91112
| UnsafeJsEval.swift:280:26:280:26 | string | UnsafeJsEval.swift:204:12:204:66 | call to String.init(contentsOf:) | UnsafeJsEval.swift:280:26:280:26 | string | Evaluation of uncontrolled JavaScript from a remote source. |
92113
| UnsafeJsEval.swift:291:17:291:17 | jsstr | UnsafeJsEval.swift:165:14:165:37 | call to String.init(contentsOf:) | UnsafeJsEval.swift:291:17:291:17 | jsstr | Evaluation of uncontrolled JavaScript from a remote source. |
93114
| UnsafeJsEval.swift:291:17:291:17 | jsstr | UnsafeJsEval.swift:204:12:204:66 | call to String.init(contentsOf:) | UnsafeJsEval.swift:291:17:291:17 | jsstr | Evaluation of uncontrolled JavaScript from a remote source. |
115+
| UnsafeJsEval.swift:305:17:305:17 | jsstr | UnsafeJsEval.swift:165:14:165:37 | call to String.init(contentsOf:) | UnsafeJsEval.swift:305:17:305:17 | jsstr | Evaluation of uncontrolled JavaScript from a remote source. |
116+
| UnsafeJsEval.swift:305:17:305:17 | jsstr | UnsafeJsEval.swift:204:12:204:66 | call to String.init(contentsOf:) | UnsafeJsEval.swift:305:17:305:17 | jsstr | Evaluation of uncontrolled JavaScript from a remote source. |
94117
| UnsafeJsEval.swift:320:44:320:74 | ... .+(_:_:) ... | UnsafeJsEval.swift:318:24:318:87 | call to String.init(contentsOf:) | UnsafeJsEval.swift:320:44:320:74 | ... .+(_:_:) ... | Evaluation of uncontrolled JavaScript from a remote source. |

0 commit comments

Comments
 (0)