Swift: Model StringProtocol initializers.

This commit is contained in:
Geoffrey White
2023-02-02 21:50:39 +00:00
parent d888510688
commit 142ca0c9fb
4 changed files with 63 additions and 3 deletions

View File

@@ -3,6 +3,9 @@ private import codeql.swift.dataflow.DataFlow
private import codeql.swift.dataflow.ExternalFlow
private import codeql.swift.dataflow.FlowSteps
/**
* A model for `String` members that are sources of remote flow.
*/
private class StringSource extends SourceModelCsv {
override predicate row(string row) {
row =
@@ -19,6 +22,20 @@ private class StringSource extends SourceModelCsv {
}
}
/**
* A model for `String` and `StringProtocol` members that permit taint flow.
*/
private class StringSummaries extends SummaryModelCsv {
override predicate row(string row) {
row =
[
";StringProtocol;true;init(cString:);;;Argument[0];ReturnValue;taint",
";StringProtocol;true;init(decoding:as:);;;Argument[0];ReturnValue;taint",
";StringProtocol;true;init(decodingCString:as:);;;Argument[0];ReturnValue;taint",
]
}
}
/**
* A content implying that, if a `String` is tainted, then all its fields are
* tainted. This also includes fields declared in `StringProtocol`.

View File

@@ -1373,7 +1373,9 @@
| string.swift:341:23:341:77 | call to String.init(data:encoding:) | string.swift:341:7:341:7 | SSA def(stringTainted) |
| string.swift:343:12:343:12 | stringClean | string.swift:343:12:343:23 | ...! |
| string.swift:344:12:344:12 | stringTainted | string.swift:344:12:344:25 | ...! |
| string.swift:346:30:346:37 | call to Data.init(_:) | string.swift:346:13:346:53 | call to String.init(decoding:as:) |
| string.swift:346:35:346:35 | | string.swift:346:30:346:37 | call to Data.init(_:) |
| string.swift:347:30:347:38 | call to source3() | string.swift:347:13:347:54 | call to String.init(decoding:as:) |
| string.swift:351:7:351:7 | SSA def(clean) | string.swift:354:3:354:3 | clean |
| string.swift:351:15:351:15 | | string.swift:351:7:351:7 | SSA def(clean) |
| string.swift:352:7:352:7 | SSA def(tainted) | string.swift:359:3:359:3 | tainted |
@@ -1420,6 +1422,7 @@
| string.swift:385:5:385:5 | buffer | string.swift:385:5:385:5 | SSA def(buffer) |
| string.swift:386:15:386:15 | buffer | string.swift:387:31:387:31 | buffer |
| string.swift:387:31:387:38 | .baseAddress | string.swift:387:31:387:49 | ...! |
| string.swift:387:31:387:49 | ...! | string.swift:387:15:387:50 | call to String.init(cString:) |
| string.swift:389:7:389:7 | SSA def(arrayString2) | string.swift:390:13:390:13 | arrayString2 |
| string.swift:389:22:389:22 | [post] tainted | string.swift:408:3:408:3 | tainted |
| string.swift:389:22:389:22 | tainted | string.swift:408:3:408:3 | tainted |
@@ -1429,6 +1432,7 @@
| string.swift:392:5:392:5 | buffer | string.swift:392:5:392:5 | SSA def(buffer) |
| string.swift:393:15:393:15 | buffer | string.swift:394:31:394:31 | buffer |
| string.swift:394:31:394:38 | .baseAddress | string.swift:394:31:394:49 | ...! |
| string.swift:394:31:394:49 | ...! | string.swift:394:15:394:50 | call to String.init(cString:) |
| string.swift:397:3:397:3 | [post] clean | string.swift:420:3:420:3 | clean |
| string.swift:397:3:397:3 | clean | string.swift:420:3:420:3 | clean |
| string.swift:398:5:398:5 | SSA def(ptr) | string.swift:399:15:399:15 | ptr |
@@ -1479,7 +1483,9 @@
| string.swift:455:27:455:27 | cleanUInt8Values | string.swift:458:29:458:29 | cleanUInt8Values |
| string.swift:456:13:456:77 | call to String.init(bytes:encoding:) | string.swift:456:13:456:78 | ...! |
| string.swift:456:27:456:27 | taintedUInt8Values | string.swift:459:29:459:29 | taintedUInt8Values |
| string.swift:458:29:458:29 | cleanUInt8Values | string.swift:458:13:458:45 | call to String.init(cString:) |
| string.swift:458:29:458:29 | cleanUInt8Values | string.swift:461:8:461:8 | cleanUInt8Values |
| string.swift:459:29:459:29 | taintedUInt8Values | string.swift:459:13:459:47 | call to String.init(cString:) |
| string.swift:459:29:459:29 | taintedUInt8Values | string.swift:467:8:467:8 | taintedUInt8Values |
| string.swift:461:8:461:8 | [post] cleanUInt8Values | string.swift:474:8:474:8 | cleanUInt8Values |
| string.swift:461:8:461:8 | cleanUInt8Values | string.swift:474:8:474:8 | cleanUInt8Values |
@@ -1491,6 +1497,7 @@
| string.swift:464:15:464:15 | buffer | string.swift:465:31:465:31 | buffer |
| string.swift:464:15:464:22 | .baseAddress | string.swift:464:15:464:33 | ...! |
| string.swift:465:31:465:38 | .baseAddress | string.swift:465:31:465:49 | ...! |
| string.swift:465:31:465:49 | ...! | string.swift:465:15:465:50 | call to String.init(cString:) |
| string.swift:467:8:467:8 | [post] taintedUInt8Values | string.swift:480:8:480:8 | taintedUInt8Values |
| string.swift:467:8:467:8 | taintedUInt8Values | string.swift:480:8:480:8 | taintedUInt8Values |
| string.swift:467:8:472:4 | call to withUnsafeBufferPointer(_:) | string.swift:467:3:472:4 | try! ... |
@@ -1501,6 +1508,7 @@
| string.swift:470:15:470:15 | buffer | string.swift:471:31:471:31 | buffer |
| string.swift:470:15:470:22 | .baseAddress | string.swift:470:15:470:33 | ...! |
| string.swift:471:31:471:38 | .baseAddress | string.swift:471:31:471:49 | ...! |
| string.swift:471:31:471:49 | ...! | string.swift:471:15:471:50 | call to String.init(cString:) |
| string.swift:474:8:474:8 | cleanUInt8Values | string.swift:474:8:474:8 | &... |
| string.swift:474:8:479:4 | call to withUnsafeMutableBytes(_:) | string.swift:474:3:479:4 | try! ... |
| string.swift:475:6:475:14 | SSA def(buffer) | string.swift:476:15:476:15 | buffer |
@@ -1548,6 +1556,7 @@
| string.swift:499:38:499:38 | ptr | string.swift:500:31:500:31 | ptr |
| string.swift:499:38:499:42 | .baseAddress | string.swift:499:38:499:53 | ...! |
| string.swift:500:31:500:35 | .baseAddress | string.swift:500:31:500:46 | ...! |
| string.swift:500:31:500:46 | ...! | string.swift:500:15:500:47 | call to String.init(cString:) |
| string.swift:502:3:502:3 | [post] taintedCCharValues | string.swift:512:29:512:29 | taintedCCharValues |
| string.swift:502:3:502:3 | taintedCCharValues | string.swift:512:29:512:29 | taintedCCharValues |
| string.swift:503:5:503:5 | SSA def(ptr) | string.swift:504:15:504:15 | ptr |
@@ -1565,6 +1574,9 @@
| string.swift:507:38:507:38 | ptr | string.swift:508:31:508:31 | ptr |
| string.swift:507:38:507:42 | .baseAddress | string.swift:507:38:507:53 | ...! |
| string.swift:508:31:508:35 | .baseAddress | string.swift:508:31:508:46 | ...! |
| string.swift:508:31:508:46 | ...! | string.swift:508:15:508:47 | call to String.init(cString:) |
| string.swift:511:29:511:29 | cleanCCharValues | string.swift:511:13:511:45 | call to String.init(cString:) |
| string.swift:512:29:512:29 | taintedCCharValues | string.swift:512:13:512:47 | call to String.init(cString:) |
| string.swift:518:7:518:35 | SSA def(cleanUnicharValues) | string.swift:521:3:521:3 | cleanUnicharValues |
| string.swift:518:39:518:59 | [...] | string.swift:518:7:518:35 | SSA def(cleanUnicharValues) |
| string.swift:519:7:519:37 | SSA def(taintedUnicharValues) | string.swift:528:3:528:3 | taintedUnicharValues |

View File

@@ -158,6 +158,9 @@ edges
| data.swift:261:22:261:29 | call to source() : | data.swift:262:12:262:12 | dataTainted41 : |
| data.swift:262:12:262:12 | dataTainted41 : | data.swift:64:2:64:72 | [summary param] this in trimmingPrefix(while:) : |
| data.swift:262:12:262:12 | dataTainted41 : | data.swift:262:12:262:54 | call to trimmingPrefix(while:) |
| file://:0:0:0:0 | [summary param] 0 in String.init(cString:) : | file://:0:0:0:0 | [summary] to write: return (return) in String.init(cString:) : |
| file://:0:0:0:0 | [summary param] 0 in String.init(cString:) : | file://:0:0:0:0 | [summary] to write: return (return) in String.init(cString:) : |
| file://:0:0:0:0 | [summary param] 0 in String.init(decoding:as:) : | file://:0:0:0:0 | [summary] to write: return (return) in String.init(decoding:as:) : |
| file://:0:0:0:0 | [summary] to write: argument 0.parameter 0 in enumerateBytes(_:) : | nsdata.swift:110:9:110:9 | bytes : |
| file://:0:0:0:0 | [summary] to write: argument 1.parameter 0 in dataTask(with:completionHandler:) : | url.swift:154:61:154:61 | data : |
| nsdata.swift:22:9:22:9 | self : | file://:0:0:0:0 | .bytes : |
@@ -606,6 +609,14 @@ edges
| string.swift:326:14:326:22 | call to source2() : | string.swift:329:13:329:13 | str5 |
| string.swift:331:14:331:22 | call to source2() : | string.swift:332:13:332:13 | str6 |
| string.swift:331:14:331:22 | call to source2() : | string.swift:334:13:334:13 | str6 |
| string.swift:347:30:347:38 | call to source3() : | file://:0:0:0:0 | [summary param] 0 in String.init(decoding:as:) : |
| string.swift:347:30:347:38 | call to source3() : | string.swift:347:13:347:54 | call to String.init(decoding:as:) |
| string.swift:436:28:436:36 | call to source4() : | string.swift:459:29:459:29 | taintedUInt8Values : |
| string.swift:459:29:459:29 | taintedUInt8Values : | file://:0:0:0:0 | [summary param] 0 in String.init(cString:) : |
| string.swift:459:29:459:29 | taintedUInt8Values : | string.swift:459:13:459:47 | call to String.init(cString:) |
| string.swift:492:37:492:45 | call to source5() : | string.swift:512:29:512:29 | taintedCCharValues : |
| string.swift:512:29:512:29 | taintedCCharValues : | file://:0:0:0:0 | [summary param] 0 in String.init(cString:) : |
| string.swift:512:29:512:29 | taintedCCharValues : | string.swift:512:13:512:47 | call to String.init(cString:) |
| string.swift:540:17:540:25 | call to source2() : | string.swift:545:13:545:13 | sub1 |
| subscript.swift:13:15:13:22 | call to source() : | subscript.swift:13:15:13:25 | ...[...] |
| subscript.swift:14:15:14:23 | call to source2() : | subscript.swift:14:15:14:26 | ...[...] |
@@ -1067,6 +1078,9 @@ nodes
| file://:0:0:0:0 | .url : | semmle.label | .url : |
| file://:0:0:0:0 | .urlContexts : | semmle.label | .urlContexts : |
| file://:0:0:0:0 | .userActivities : | semmle.label | .userActivities : |
| file://:0:0:0:0 | [summary param] 0 in String.init(cString:) : | semmle.label | [summary param] 0 in String.init(cString:) : |
| file://:0:0:0:0 | [summary param] 0 in String.init(cString:) : | semmle.label | [summary param] 0 in String.init(cString:) : |
| file://:0:0:0:0 | [summary param] 0 in String.init(decoding:as:) : | semmle.label | [summary param] 0 in String.init(decoding:as:) : |
| file://:0:0:0:0 | [summary] to write: argument 0 in copyBytes(to:) : | semmle.label | [summary] to write: argument 0 in copyBytes(to:) : |
| file://:0:0:0:0 | [summary] to write: argument 0 in getBytes(_:) : | semmle.label | [summary] to write: argument 0 in getBytes(_:) : |
| file://:0:0:0:0 | [summary] to write: argument 0 in getBytes(_:length:) : | semmle.label | [summary] to write: argument 0 in getBytes(_:length:) : |
@@ -1124,6 +1138,9 @@ nodes
| file://:0:0:0:0 | [summary] to write: return (return) in NSData.init(contentsOfFile:options:) : | semmle.label | [summary] to write: return (return) in NSData.init(contentsOfFile:options:) : |
| file://:0:0:0:0 | [summary] to write: return (return) in NSData.init(contentsOfMappedFile:) : | semmle.label | [summary] to write: return (return) in NSData.init(contentsOfMappedFile:) : |
| file://:0:0:0:0 | [summary] to write: return (return) in NSData.init(data:) : | semmle.label | [summary] to write: return (return) in NSData.init(data:) : |
| file://:0:0:0:0 | [summary] to write: return (return) in String.init(cString:) : | semmle.label | [summary] to write: return (return) in String.init(cString:) : |
| file://:0:0:0:0 | [summary] to write: return (return) in String.init(cString:) : | semmle.label | [summary] to write: return (return) in String.init(cString:) : |
| file://:0:0:0:0 | [summary] to write: return (return) in String.init(decoding:as:) : | semmle.label | [summary] to write: return (return) in String.init(decoding:as:) : |
| file://:0:0:0:0 | [summary] to write: return (return) in URL.init(string:) : | semmle.label | [summary] to write: return (return) in URL.init(string:) : |
| file://:0:0:0:0 | [summary] to write: return (return) in URL.init(string:relativeTo:) : | semmle.label | [summary] to write: return (return) in URL.init(string:relativeTo:) : |
| file://:0:0:0:0 | [summary] to write: return (return) in URL.init(string:relativeTo:) : | semmle.label | [summary] to write: return (return) in URL.init(string:relativeTo:) : |
@@ -1393,6 +1410,14 @@ nodes
| string.swift:331:14:331:22 | call to source2() : | semmle.label | call to source2() : |
| string.swift:332:13:332:13 | str6 | semmle.label | str6 |
| string.swift:334:13:334:13 | str6 | semmle.label | str6 |
| string.swift:347:13:347:54 | call to String.init(decoding:as:) | semmle.label | call to String.init(decoding:as:) |
| string.swift:347:30:347:38 | call to source3() : | semmle.label | call to source3() : |
| string.swift:436:28:436:36 | call to source4() : | semmle.label | call to source4() : |
| string.swift:459:13:459:47 | call to String.init(cString:) | semmle.label | call to String.init(cString:) |
| string.swift:459:29:459:29 | taintedUInt8Values : | semmle.label | taintedUInt8Values : |
| string.swift:492:37:492:45 | call to source5() : | semmle.label | call to source5() : |
| string.swift:512:13:512:47 | call to String.init(cString:) | semmle.label | call to String.init(cString:) |
| string.swift:512:29:512:29 | taintedCCharValues : | semmle.label | taintedCCharValues : |
| string.swift:540:17:540:25 | call to source2() : | semmle.label | call to source2() : |
| string.swift:542:13:542:21 | call to source7() | semmle.label | call to source7() |
| string.swift:545:13:545:13 | sub1 | semmle.label | sub1 |
@@ -1713,6 +1738,9 @@ subpaths
| string.swift:250:13:250:13 | tainted : | string.swift:107:8:107:8 | self : | string.swift:107:3:107:78 | self[return] : | string.swift:250:13:250:13 | [post] tainted : |
| string.swift:251:13:251:13 | tainted : | string.swift:107:8:107:8 | self : | string.swift:107:3:107:78 | self[return] : | string.swift:251:13:251:13 | [post] tainted : |
| string.swift:258:13:258:13 | tainted : | string.swift:109:8:109:8 | self : | string.swift:109:3:109:79 | self[return] : | string.swift:258:13:258:13 | [post] tainted : |
| string.swift:347:30:347:38 | call to source3() : | file://:0:0:0:0 | [summary param] 0 in String.init(decoding:as:) : | file://:0:0:0:0 | [summary] to write: return (return) in String.init(decoding:as:) : | string.swift:347:13:347:54 | call to String.init(decoding:as:) |
| string.swift:459:29:459:29 | taintedUInt8Values : | file://:0:0:0:0 | [summary param] 0 in String.init(cString:) : | file://:0:0:0:0 | [summary] to write: return (return) in String.init(cString:) : | string.swift:459:13:459:47 | call to String.init(cString:) |
| string.swift:512:29:512:29 | taintedCCharValues : | file://:0:0:0:0 | [summary param] 0 in String.init(cString:) : | file://:0:0:0:0 | [summary] to write: return (return) in String.init(cString:) : | string.swift:512:13:512:47 | call to String.init(cString:) |
| ui.swift:55:10:55:10 | tainted : | ui.swift:16:9:16:9 | self : | file://:0:0:0:0 | .url : | ui.swift:55:10:55:18 | .url |
| ui.swift:64:10:64:10 | tainted : | ui.swift:32:13:32:13 | self : | file://:0:0:0:0 | .userActivities : | ui.swift:64:10:64:18 | .userActivities |
| ui.swift:68:10:68:10 | tainted : | ui.swift:34:13:34:13 | self : | file://:0:0:0:0 | .urlContexts : | ui.swift:68:10:68:18 | .urlContexts |
@@ -1885,6 +1913,9 @@ subpaths
| string.swift:329:13:329:13 | str5 | string.swift:326:14:326:22 | call to source2() : | string.swift:329:13:329:13 | str5 | result |
| string.swift:332:13:332:13 | str6 | string.swift:331:14:331:22 | call to source2() : | string.swift:332:13:332:13 | str6 | result |
| string.swift:334:13:334:13 | str6 | string.swift:331:14:331:22 | call to source2() : | string.swift:334:13:334:13 | str6 | result |
| string.swift:347:13:347:54 | call to String.init(decoding:as:) | string.swift:347:30:347:38 | call to source3() : | string.swift:347:13:347:54 | call to String.init(decoding:as:) | result |
| string.swift:459:13:459:47 | call to String.init(cString:) | string.swift:436:28:436:36 | call to source4() : | string.swift:459:13:459:47 | call to String.init(cString:) | result |
| string.swift:512:13:512:47 | call to String.init(cString:) | string.swift:492:37:492:45 | call to source5() : | string.swift:512:13:512:47 | call to String.init(cString:) | result |
| string.swift:542:13:542:21 | call to source7() | string.swift:542:13:542:21 | call to source7() | string.swift:542:13:542:21 | call to source7() | result |
| string.swift:545:13:545:13 | sub1 | string.swift:540:17:540:25 | call to source2() : | string.swift:545:13:545:13 | sub1 | result |
| subscript.swift:13:15:13:25 | ...[...] | subscript.swift:13:15:13:22 | call to source() : | subscript.swift:13:15:13:25 | ...[...] | result |

View File

@@ -344,7 +344,7 @@ func taintThroughData() {
sink(arg: stringTainted!) // $ MISSING: tainted=341
sink(arg: String(decoding: Data(""), as: UTF8.self))
sink(arg: String(decoding: source3(), as: UTF8.self)) // $ MISSING: tainted=347
sink(arg: String(decoding: source3(), as: UTF8.self)) // $ tainted=347
}
func taintThroughEncodings() {
@@ -456,7 +456,7 @@ func taintFromUInt8Array() {
sink(arg: String(bytes: taintedUInt8Values, encoding: String.Encoding.utf8)!) // $ MISSING: tainted=436
sink(arg: String(cString: cleanUInt8Values))
sink(arg: String(cString: taintedUInt8Values)) // $ MISSING: tainted=436
sink(arg: String(cString: taintedUInt8Values)) // $ tainted=436
try! cleanUInt8Values.withUnsafeBufferPointer({
(buffer: UnsafeBufferPointer<UInt8>) throws in
@@ -509,7 +509,7 @@ func taintThroughCCharArray() {
})
sink(arg: String(cString: cleanCCharValues))
sink(arg: String(cString: taintedCCharValues)) // $ MISSING: tainted=492
sink(arg: String(cString: taintedCCharValues)) // $ tainted=492
}
func source6() -> [unichar] { return [] }