From e86ccf8498e7ff40e610da1dfe33c33e4676a985 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 9 Aug 2023 17:06:15 +0100 Subject: [PATCH 01/20] Swift: Test flow through various conversions. --- .../dataflow/taint/core/LocalTaint.expected | 79 ++++++++++++++ .../dataflow/taint/core/Taint.expected | 37 +++++++ .../dataflow/taint/core/conversions.swift | 101 ++++++++++++++++++ 3 files changed, 217 insertions(+) create mode 100644 swift/ql/test/library-tests/dataflow/taint/core/conversions.swift diff --git a/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected b/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected index b7408d1f57e0..65fe7171c3ff 100644 --- a/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected @@ -1,3 +1,82 @@ +| conversions.swift:9:7:9:7 | SSA def(self) | conversions.swift:9:7:9:7 | self[return] | +| conversions.swift:9:7:9:7 | SSA def(self) | conversions.swift:9:7:9:7 | self[return] | +| conversions.swift:9:7:9:7 | self | conversions.swift:9:7:9:7 | SSA def(self) | +| conversions.swift:9:7:9:7 | self | conversions.swift:9:7:9:7 | SSA def(self) | +| conversions.swift:12:7:12:7 | SSA def(self) | conversions.swift:12:7:12:7 | self[return] | +| conversions.swift:12:7:12:7 | self | conversions.swift:12:7:12:7 | SSA def(self) | +| conversions.swift:12:36:12:36 | SSA def(self) | conversions.swift:12:36:12:36 | self[return] | +| conversions.swift:12:36:12:36 | self | conversions.swift:12:36:12:36 | SSA def(self) | +| conversions.swift:15:7:15:7 | SSA def(self) | conversions.swift:15:7:15:7 | self[return] | +| conversions.swift:15:7:15:7 | self | conversions.swift:15:7:15:7 | SSA def(self) | +| conversions.swift:16:11:16:11 | SSA def(self) | conversions.swift:16:11:16:42 | self[return] | +| conversions.swift:16:11:16:11 | self | conversions.swift:16:11:16:11 | SSA def(self) | +| conversions.swift:18:28:18:28 | SSA def(self) | conversions.swift:18:28:18:44 | self[return] | +| conversions.swift:18:28:18:28 | self | conversions.swift:18:28:18:28 | SSA def(self) | +| conversions.swift:19:33:19:33 | SSA def(self) | conversions.swift:19:33:19:49 | self[return] | +| conversions.swift:19:33:19:33 | self | conversions.swift:19:33:19:33 | SSA def(self) | +| conversions.swift:20:22:20:22 | SSA def(self) | conversions.swift:20:22:20:38 | self[return] | +| conversions.swift:20:22:20:22 | self | conversions.swift:20:22:20:22 | SSA def(self) | +| conversions.swift:28:19:28:29 | call to sourceInt() | conversions.swift:28:12:28:30 | call to String.init(_:) | +| conversions.swift:29:12:29:30 | call to String.init(_:) | conversions.swift:29:12:29:32 | .utf8 | +| conversions.swift:29:19:29:29 | call to sourceInt() | conversions.swift:29:12:29:30 | call to String.init(_:) | +| conversions.swift:30:20:30:33 | call to sourceString() | conversions.swift:30:20:30:35 | .utf8 | +| conversions.swift:32:9:32:9 | SSA def(v) | conversions.swift:33:13:33:13 | v | +| conversions.swift:32:9:32:9 | v | conversions.swift:32:9:32:9 | SSA def(v) | +| conversions.swift:32:13:32:23 | call to sourceInt() | conversions.swift:32:5:32:9 | let ...? | +| conversions.swift:36:6:36:6 | SSA def(v2) | conversions.swift:37:12:37:12 | v2 | +| conversions.swift:36:6:36:6 | v2 | conversions.swift:36:6:36:6 | SSA def(v2) | +| conversions.swift:36:6:36:10 | ... as ... | conversions.swift:36:6:36:6 | v2 | +| conversions.swift:36:18:36:41 | call to numericCast(_:) | conversions.swift:36:6:36:10 | ... as ... | +| conversions.swift:39:6:39:6 | SSA def(v4) | conversions.swift:40:12:40:12 | v4 | +| conversions.swift:39:6:39:6 | v4 | conversions.swift:39:6:39:6 | SSA def(v4) | +| conversions.swift:39:6:39:10 | ... as ... | conversions.swift:39:6:39:6 | v4 | +| conversions.swift:39:17:39:57 | call to unsafeBitCast(_:to:) | conversions.swift:39:6:39:10 | ... as ... | +| conversions.swift:42:6:42:6 | SSA def(v5) | conversions.swift:43:12:43:12 | v5 | +| conversions.swift:42:6:42:6 | v5 | conversions.swift:42:6:42:6 | SSA def(v5) | +| conversions.swift:42:11:42:47 | call to Self.init(truncatingIfNeeded:) | conversions.swift:42:6:42:6 | v5 | +| conversions.swift:45:6:45:6 | SSA def(v6) | conversions.swift:46:12:46:12 | v6 | +| conversions.swift:45:6:45:6 | v6 | conversions.swift:45:6:45:6 | SSA def(v6) | +| conversions.swift:45:11:45:39 | call to UInt.init(bitPattern:) | conversions.swift:45:6:45:6 | v6 | +| conversions.swift:48:12:48:36 | call to Self.init(exactly:) | conversions.swift:48:12:48:37 | ...! | +| conversions.swift:51:12:51:41 | call to Self.init(_:radix:) | conversions.swift:51:12:51:42 | ...! | +| conversions.swift:63:19:63:31 | call to sourceFloat() | conversions.swift:63:12:63:32 | call to String.init(_:) | +| conversions.swift:64:12:64:32 | call to String.init(_:) | conversions.swift:64:12:64:34 | .utf8 | +| conversions.swift:64:19:64:31 | call to sourceFloat() | conversions.swift:64:12:64:32 | call to String.init(_:) | +| conversions.swift:78:19:78:32 | call to sourceString() | conversions.swift:78:12:78:33 | call to String.init(_:) | +| conversions.swift:80:6:80:6 | SSA def(ms1) | conversions.swift:81:12:81:12 | ms1 | +| conversions.swift:80:6:80:6 | ms1 | conversions.swift:80:6:80:6 | SSA def(ms1) | +| conversions.swift:80:12:80:26 | call to MyString.init(_:) | conversions.swift:80:12:80:27 | ...! | +| conversions.swift:80:12:80:27 | ...! | conversions.swift:80:6:80:6 | ms1 | +| conversions.swift:81:12:81:12 | [post] ms1 | conversions.swift:82:12:82:12 | ms1 | +| conversions.swift:81:12:81:12 | ms1 | conversions.swift:82:12:82:12 | ms1 | +| conversions.swift:82:12:82:12 | [post] ms1 | conversions.swift:83:12:83:12 | ms1 | +| conversions.swift:82:12:82:12 | ms1 | conversions.swift:83:12:83:12 | ms1 | +| conversions.swift:83:12:83:12 | [post] ms1 | conversions.swift:84:12:84:12 | ms1 | +| conversions.swift:83:12:83:12 | ms1 | conversions.swift:84:12:84:12 | ms1 | +| conversions.swift:86:6:86:6 | SSA def(ms2) | conversions.swift:87:12:87:12 | ms2 | +| conversions.swift:86:6:86:6 | ms2 | conversions.swift:86:6:86:6 | SSA def(ms2) | +| conversions.swift:86:12:86:35 | call to MyString.init(_:) | conversions.swift:86:12:86:36 | ...! | +| conversions.swift:86:12:86:36 | ...! | conversions.swift:86:6:86:6 | ms2 | +| conversions.swift:87:12:87:12 | [post] ms2 | conversions.swift:88:12:88:12 | ms2 | +| conversions.swift:87:12:87:12 | ms2 | conversions.swift:88:12:88:12 | ms2 | +| conversions.swift:88:12:88:12 | [post] ms2 | conversions.swift:89:12:89:12 | ms2 | +| conversions.swift:88:12:88:12 | ms2 | conversions.swift:89:12:89:12 | ms2 | +| conversions.swift:89:12:89:12 | [post] ms2 | conversions.swift:90:12:90:12 | ms2 | +| conversions.swift:89:12:89:12 | ms2 | conversions.swift:90:12:90:12 | ms2 | +| conversions.swift:94:6:94:6 | SSA def(parent) | conversions.swift:95:12:95:12 | parent | +| conversions.swift:94:6:94:6 | parent | conversions.swift:94:6:94:6 | SSA def(parent) | +| conversions.swift:94:6:94:15 | ... as ... | conversions.swift:94:6:94:6 | parent | +| conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:94:6:94:15 | ... as ... | +| conversions.swift:95:12:95:12 | [post] parent | conversions.swift:96:12:96:12 | parent | +| conversions.swift:95:12:95:12 | parent | conversions.swift:96:12:96:12 | parent | +| conversions.swift:96:12:96:12 | [post] parent | conversions.swift:98:40:98:40 | parent | +| conversions.swift:96:12:96:12 | parent | conversions.swift:98:40:98:40 | parent | +| conversions.swift:98:6:98:6 | SSA def(v3) | conversions.swift:99:12:99:12 | v3 | +| conversions.swift:98:6:98:6 | v3 | conversions.swift:98:6:98:6 | SSA def(v3) | +| conversions.swift:98:6:98:10 | ... as ... | conversions.swift:98:6:98:6 | v3 | +| conversions.swift:98:25:98:69 | call to unsafeDowncast(_:to:) | conversions.swift:98:6:98:10 | ... as ... | +| conversions.swift:99:12:99:12 | [post] v3 | conversions.swift:100:12:100:12 | v3 | +| conversions.swift:99:12:99:12 | v3 | conversions.swift:100:12:100:12 | v3 | | simple.swift:12:13:12:13 | 1 | simple.swift:12:13:12:24 | ... .+(_:_:) ... | | simple.swift:12:17:12:24 | call to source() | simple.swift:12:13:12:24 | ... .+(_:_:) ... | | simple.swift:13:13:13:20 | call to source() | simple.swift:13:13:13:24 | ... .+(_:_:) ... | diff --git a/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected b/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected index 3438ed3afebd..6923c1e8ec15 100644 --- a/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected @@ -1,4 +1,13 @@ edges +| conversions.swift:28:19:28:29 | call to sourceInt() | conversions.swift:28:12:28:30 | call to String.init(_:) | +| conversions.swift:29:12:29:30 | call to String.init(_:) | conversions.swift:29:12:29:32 | .utf8 | +| conversions.swift:29:19:29:29 | call to sourceInt() | conversions.swift:29:12:29:30 | call to String.init(_:) | +| conversions.swift:63:19:63:31 | call to sourceFloat() | conversions.swift:63:12:63:32 | call to String.init(_:) | +| conversions.swift:64:12:64:32 | call to String.init(_:) | conversions.swift:64:12:64:34 | .utf8 | +| conversions.swift:64:19:64:31 | call to sourceFloat() | conversions.swift:64:12:64:32 | call to String.init(_:) | +| conversions.swift:78:19:78:32 | call to sourceString() | conversions.swift:78:12:78:33 | call to String.init(_:) | +| conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:95:12:95:12 | parent | +| conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:96:12:96:12 | parent | | file://:0:0:0:0 | self [first] | file://:0:0:0:0 | .first | | file://:0:0:0:0 | self [second] | file://:0:0:0:0 | .second | | file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [first] | @@ -77,6 +86,24 @@ edges | try.swift:18:18:18:25 | call to source() | try.swift:18:18:18:25 | call to source() [some:0] | | try.swift:18:18:18:25 | call to source() [some:0] | try.swift:18:13:18:25 | try? ... [some:0] | nodes +| conversions.swift:24:12:24:22 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:28:12:28:30 | call to String.init(_:) | semmle.label | call to String.init(_:) | +| conversions.swift:28:19:28:29 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:29:12:29:30 | call to String.init(_:) | semmle.label | call to String.init(_:) | +| conversions.swift:29:12:29:32 | .utf8 | semmle.label | .utf8 | +| conversions.swift:29:19:29:29 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:60:12:60:24 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:63:12:63:32 | call to String.init(_:) | semmle.label | call to String.init(_:) | +| conversions.swift:63:19:63:31 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:64:12:64:32 | call to String.init(_:) | semmle.label | call to String.init(_:) | +| conversions.swift:64:12:64:34 | .utf8 | semmle.label | .utf8 | +| conversions.swift:64:19:64:31 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:77:12:77:25 | call to sourceString() | semmle.label | call to sourceString() | +| conversions.swift:78:12:78:33 | call to String.init(_:) | semmle.label | call to String.init(_:) | +| conversions.swift:78:19:78:32 | call to sourceString() | semmle.label | call to sourceString() | +| conversions.swift:94:31:94:44 | call to sourceString() | semmle.label | call to sourceString() | +| conversions.swift:95:12:95:12 | parent | semmle.label | parent | +| conversions.swift:96:12:96:12 | parent | semmle.label | parent | | file://:0:0:0:0 | .first | semmle.label | .first | | file://:0:0:0:0 | .second | semmle.label | .second | | file://:0:0:0:0 | [post] self [first] | semmle.label | [post] self [first] | @@ -200,6 +227,16 @@ subpaths | stringinterpolation.swift:28:14:28:21 | call to source() | stringinterpolation.swift:7:6:7:6 | value | file://:0:0:0:0 | [post] self [second] | stringinterpolation.swift:28:2:28:2 | [post] p2 [second] | | stringinterpolation.swift:31:21:31:21 | p2 [second] | stringinterpolation.swift:7:6:7:6 | self [second] | file://:0:0:0:0 | .second | stringinterpolation.swift:31:21:31:24 | .second | #select +| conversions.swift:24:12:24:22 | call to sourceInt() | conversions.swift:24:12:24:22 | call to sourceInt() | conversions.swift:24:12:24:22 | call to sourceInt() | result | +| conversions.swift:28:12:28:30 | call to String.init(_:) | conversions.swift:28:19:28:29 | call to sourceInt() | conversions.swift:28:12:28:30 | call to String.init(_:) | result | +| conversions.swift:29:12:29:32 | .utf8 | conversions.swift:29:19:29:29 | call to sourceInt() | conversions.swift:29:12:29:32 | .utf8 | result | +| conversions.swift:60:12:60:24 | call to sourceFloat() | conversions.swift:60:12:60:24 | call to sourceFloat() | conversions.swift:60:12:60:24 | call to sourceFloat() | result | +| conversions.swift:63:12:63:32 | call to String.init(_:) | conversions.swift:63:19:63:31 | call to sourceFloat() | conversions.swift:63:12:63:32 | call to String.init(_:) | result | +| conversions.swift:64:12:64:34 | .utf8 | conversions.swift:64:19:64:31 | call to sourceFloat() | conversions.swift:64:12:64:34 | .utf8 | result | +| conversions.swift:77:12:77:25 | call to sourceString() | conversions.swift:77:12:77:25 | call to sourceString() | conversions.swift:77:12:77:25 | call to sourceString() | result | +| conversions.swift:78:12:78:33 | call to String.init(_:) | conversions.swift:78:19:78:32 | call to sourceString() | conversions.swift:78:12:78:33 | call to String.init(_:) | result | +| conversions.swift:95:12:95:12 | parent | conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:95:12:95:12 | parent | result | +| conversions.swift:96:12:96:12 | parent | conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:96:12:96:12 | parent | result | | simple.swift:12:13:12:24 | ... .+(_:_:) ... | simple.swift:12:17:12:24 | call to source() | simple.swift:12:13:12:24 | ... .+(_:_:) ... | result | | simple.swift:13:13:13:24 | ... .+(_:_:) ... | simple.swift:13:13:13:20 | call to source() | simple.swift:13:13:13:24 | ... .+(_:_:) ... | result | | simple.swift:14:13:14:24 | ... .-(_:_:) ... | simple.swift:14:17:14:24 | call to source() | simple.swift:14:13:14:24 | ... .-(_:_:) ... | result | diff --git a/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift b/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift new file mode 100644 index 000000000000..4789486ad456 --- /dev/null +++ b/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift @@ -0,0 +1,101 @@ + +func sourceInt() -> Int { 0 } +func sourceFloat() -> Float { 0.0 } +func sourceString() -> String { "" } +func sink(arg: Any) { } + +// --- + +class MyParentClass { +} + +class MyChildClass : MyParentClass { +} + +class MyString : LosslessStringConvertible, CustomStringConvertible, CustomDebugStringConvertible { + required init?(_ description: String) { } + + var description: String { get { return "" } } + var debugDescription: String { get { return "" } } + var clean: String { get { return "" } } +} + +func testConversions() { + sink(arg: sourceInt()) // $ tainted=24 + sink(arg: Int(sourceInt())) // $ MISSING: tainted= + sink(arg: UInt8(sourceInt())) // $ MISSING: tainted= + sink(arg: Float(sourceInt())) // $ MISSING: tainted= + sink(arg: String(sourceInt())) // $ tainted=28 + sink(arg: String(sourceInt()).utf8) // $ tainted=29 + sink(arg: [UInt8](sourceString().utf8)) // $ MISSING: tainted= + + if let v = sourceInt() as? UInt { + sink(arg: v) // $ MISSING: tainted= + } + + let v2: UInt8 = numericCast(sourceInt()) + sink(arg: v2) // $ MISSING: tainted= + + let v4: UInt = unsafeBitCast(sourceInt(), to: UInt.self) + sink(arg: v4) // $ MISSING: tainted= + + let v5 = UInt(truncatingIfNeeded: sourceInt()) + sink(arg: v5) // $ MISSING: tainted= + + let v6 = UInt(bitPattern: sourceInt()) + sink(arg: v6) // $ MISSING: tainted= + + sink(arg: Int(exactly: sourceInt())!) // $ MISSING: tainted= + sink(arg: Int(clamping: sourceInt())) // $ MISSING: tainted= + sink(arg: Int(truncatingIfNeeded: sourceInt())) // $ MISSING: tainted= + sink(arg: Int(sourceString(), radix: 10)!) // $ MISSING: tainted= + + sink(arg: Int(littleEndian: sourceInt())) // $ MISSING: tainted= + sink(arg: Int(bigEndian: sourceInt())) // $ MISSING: tainted= + sink(arg: sourceInt().littleEndian) // $ MISSING: tainted= + sink(arg: sourceInt().bigEndian) // $ MISSING: tainted= + + // --- + + sink(arg: sourceFloat()) // $ tainted=60 + sink(arg: Float(sourceFloat())) // $ MISSING: tainted= + sink(arg: UInt8(sourceFloat())) // $ MISSING: tainted= + sink(arg: String(sourceFloat())) // $ tainted=63 + sink(arg: String(sourceFloat()).utf8) // $ tainted=64 + + sink(arg: Float(sourceFloat())) // MISSING: tainted= + sink(arg: Float(sign: .plus, exponent: sourceInt(), significand: 0.0)) // MISSING: tainted= + sink(arg: Float(sign: .plus, exponent: 0, significand: sourceFloat())) // MISSING: tainted= + sink(arg: Float(signOf: sourceFloat(), magnitudeOf: 0.0)) // (good) + sink(arg: Float(signOf: 0.0, magnitudeOf: sourceFloat())) // MISSING: tainted= + + sink(arg: sourceFloat().exponent) // $ MISSING: tainted= + sink(arg: sourceFloat().significand) // $ MISSING: tainted= + + // --- + + sink(arg: sourceString()) // $ tainted=77 + sink(arg: String(sourceString())) // $ tainted=78 + + let ms1 = MyString("abc")! + sink(arg: ms1) + sink(arg: ms1.description) + sink(arg: ms1.debugDescription) + sink(arg: ms1.clean) + + let ms2 = MyString(sourceString())! + sink(arg: ms2) // $ MISSING: tainted= + sink(arg: ms2.description) // $ MISSING: tainted= + sink(arg: ms2.debugDescription) // $ MISSING: tainted= + sink(arg: ms2.clean) + + // --- + + let parent : MyParentClass = sourceString() as! MyChildClass + sink(arg: parent) // $ tainted=94 + sink(arg: parent as! MyChildClass) // $ tainted=94 + + let v3: MyChildClass = unsafeDowncast(parent, to: MyChildClass.self) + sink(arg: v3) // $ MISSING: tainted= + sink(arg: v3 as! MyParentClass) // $ MISSING: tainted= +} From aa2e79b6da4c1d53efe12c2970703104d9cd99b1 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 9 Aug 2023 20:57:43 +0100 Subject: [PATCH 02/20] Swift: Model numeric conversions. --- .../frameworks/StandardLibrary/Numeric.qll | 51 ++++++++ .../StandardLibrary/StandardLibrary.qll | 1 + .../dataflow/taint/core/LocalTaint.expected | 26 ++++ .../dataflow/taint/core/Taint.expected | 114 ++++++++++++++++++ .../dataflow/taint/core/conversions.swift | 50 ++++---- 5 files changed, 217 insertions(+), 25 deletions(-) create mode 100644 swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Numeric.qll diff --git a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Numeric.qll b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Numeric.qll new file mode 100644 index 000000000000..a985bb7f0ed4 --- /dev/null +++ b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Numeric.qll @@ -0,0 +1,51 @@ +/** + * Provides models for `Numeric` and related Swift classes (such as `Int` and `Float`). + */ + +import swift +private import codeql.swift.dataflow.DataFlow +private import codeql.swift.dataflow.ExternalFlow +private import codeql.swift.dataflow.FlowSteps + +/** + * A model for `Numeric` and related class members and functions that permit taint flow. + */ +private class NumericSummaries extends SummaryModelCsv { + override predicate row(string row) { + row = + [ + ";;false;numericCast(_:);;;Argument[0];ReturnValue;taint", + ";;false;unsafeDowncast(_:to:);;;Argument[0];ReturnValue;taint", + ";;false;unsafeBitCast(_:to:);;;Argument[0];ReturnValue;taint", + ";Numeric;true;init(exactly:);;;Argument[0];ReturnValue.OptionalSome;value", + ";Numeric;true;init(bitPattern:);;;Argument[0];ReturnValue;taint", + ";BinaryInteger;true;init(_:);;;Argument[0];ReturnValue;taint", + ";BinaryInteger;true;init(clamping:);;;Argument[0];ReturnValue;taint", + ";BinaryInteger;true;init(truncatingIfNeeded:);;;Argument[0];ReturnValue;taint", + ";BinaryInteger;true;init(_:format:lenient:);;;Argument[0];ReturnValue;taint", + ";BinaryInteger;true;init(_:strategy:);;;Argument[0];ReturnValue;taint", + ";BinaryInteger;true;formatted();;;Argument[-1];ReturnValue;taint", + ";BinaryInteger;true;formatted(_:);;;Argument[-1];ReturnValue;taint", + ";FixedWidthInteger;true;init(_:radix:);;;Argument[0];ReturnValue;taint", + ";FixedWidthInteger;true;init(littleEndian:);;;Argument[0];ReturnValue;taint", + ";FixedWidthInteger;true;init(bigEndian:);;;Argument[0];ReturnValue;taint", + ";FloatingPoint;true;init(_:);;;Argument[0];ReturnValue;taint", + ";FloatingPoint;true;init(sign:exponent:significand:);;;Argument[1..2];ReturnValue;taint", + ";FloatingPoint;true;init(signOf:magnitudeOf:);;;Argument[1];ReturnValue;taint", + ] + } +} + +/** + * A content implying that, if a `Numeric` is tainted, then some of its fields are + * tainted. + */ +private class NumericFieldsInheritTaint extends TaintInheritingContent, + DataFlow::Content::FieldContent +{ + NumericFieldsInheritTaint() { + this.getField().hasQualifiedName("FixedWidthInteger", ["littleEndian", "bigEndian"]) + or + this.getField().hasQualifiedName(["Double", "Float", "Float80", "FloatingPoint"], ["exponent", "significand"]) + } +} diff --git a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/StandardLibrary.qll b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/StandardLibrary.qll index 93d60dba092d..775c6afcea0f 100644 --- a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/StandardLibrary.qll +++ b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/StandardLibrary.qll @@ -14,6 +14,7 @@ private import NsData private import NsObject private import NsString private import NsUrl +private import Numeric private import Sequence private import Set private import String diff --git a/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected b/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected index 65fe7171c3ff..1ff797add875 100644 --- a/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected @@ -16,6 +16,9 @@ | conversions.swift:19:33:19:33 | self | conversions.swift:19:33:19:33 | SSA def(self) | | conversions.swift:20:22:20:22 | SSA def(self) | conversions.swift:20:22:20:38 | self[return] | | conversions.swift:20:22:20:22 | self | conversions.swift:20:22:20:22 | SSA def(self) | +| conversions.swift:25:16:25:26 | call to sourceInt() | conversions.swift:25:12:25:27 | call to Self.init(_:) | +| conversions.swift:26:18:26:28 | call to sourceInt() | conversions.swift:26:12:26:29 | call to Self.init(_:) | +| conversions.swift:27:18:27:28 | call to sourceInt() | conversions.swift:27:12:27:29 | call to Float.init(_:) | | conversions.swift:28:19:28:29 | call to sourceInt() | conversions.swift:28:12:28:30 | call to String.init(_:) | | conversions.swift:29:12:29:30 | call to String.init(_:) | conversions.swift:29:12:29:32 | .utf8 | | conversions.swift:29:19:29:29 | call to sourceInt() | conversions.swift:29:12:29:30 | call to String.init(_:) | @@ -27,21 +30,43 @@ | conversions.swift:36:6:36:6 | v2 | conversions.swift:36:6:36:6 | SSA def(v2) | | conversions.swift:36:6:36:10 | ... as ... | conversions.swift:36:6:36:6 | v2 | | conversions.swift:36:18:36:41 | call to numericCast(_:) | conversions.swift:36:6:36:10 | ... as ... | +| conversions.swift:36:30:36:40 | call to sourceInt() | conversions.swift:36:18:36:41 | call to numericCast(_:) | | conversions.swift:39:6:39:6 | SSA def(v4) | conversions.swift:40:12:40:12 | v4 | | conversions.swift:39:6:39:6 | v4 | conversions.swift:39:6:39:6 | SSA def(v4) | | conversions.swift:39:6:39:10 | ... as ... | conversions.swift:39:6:39:6 | v4 | | conversions.swift:39:17:39:57 | call to unsafeBitCast(_:to:) | conversions.swift:39:6:39:10 | ... as ... | +| conversions.swift:39:31:39:41 | call to sourceInt() | conversions.swift:39:17:39:57 | call to unsafeBitCast(_:to:) | | conversions.swift:42:6:42:6 | SSA def(v5) | conversions.swift:43:12:43:12 | v5 | | conversions.swift:42:6:42:6 | v5 | conversions.swift:42:6:42:6 | SSA def(v5) | | conversions.swift:42:11:42:47 | call to Self.init(truncatingIfNeeded:) | conversions.swift:42:6:42:6 | v5 | +| conversions.swift:42:36:42:46 | call to sourceInt() | conversions.swift:42:11:42:47 | call to Self.init(truncatingIfNeeded:) | | conversions.swift:45:6:45:6 | SSA def(v6) | conversions.swift:46:12:46:12 | v6 | | conversions.swift:45:6:45:6 | v6 | conversions.swift:45:6:45:6 | SSA def(v6) | | conversions.swift:45:11:45:39 | call to UInt.init(bitPattern:) | conversions.swift:45:6:45:6 | v6 | +| conversions.swift:45:28:45:38 | call to sourceInt() | conversions.swift:45:11:45:39 | call to UInt.init(bitPattern:) | | conversions.swift:48:12:48:36 | call to Self.init(exactly:) | conversions.swift:48:12:48:37 | ...! | +| conversions.swift:49:26:49:36 | call to sourceInt() | conversions.swift:49:12:49:37 | call to Self.init(clamping:) | +| conversions.swift:50:36:50:46 | call to sourceInt() | conversions.swift:50:12:50:47 | call to Self.init(truncatingIfNeeded:) | | conversions.swift:51:12:51:41 | call to Self.init(_:radix:) | conversions.swift:51:12:51:42 | ...! | +| conversions.swift:51:16:51:29 | call to sourceString() | conversions.swift:51:12:51:41 | call to Self.init(_:radix:) | +| conversions.swift:53:30:53:40 | call to sourceInt() | conversions.swift:53:12:53:41 | call to Self.init(littleEndian:) | +| conversions.swift:54:27:54:37 | call to sourceInt() | conversions.swift:54:12:54:38 | call to Self.init(bigEndian:) | +| conversions.swift:55:12:55:22 | call to sourceInt() | conversions.swift:55:12:55:24 | .littleEndian | +| conversions.swift:56:12:56:22 | call to sourceInt() | conversions.swift:56:12:56:24 | .bigEndian | +| conversions.swift:61:18:61:30 | call to sourceFloat() | conversions.swift:61:12:61:31 | call to Float.init(_:) | +| conversions.swift:62:18:62:30 | call to sourceFloat() | conversions.swift:62:12:62:31 | call to UInt8.init(_:) | | conversions.swift:63:19:63:31 | call to sourceFloat() | conversions.swift:63:12:63:32 | call to String.init(_:) | | conversions.swift:64:12:64:32 | call to String.init(_:) | conversions.swift:64:12:64:34 | .utf8 | | conversions.swift:64:19:64:31 | call to sourceFloat() | conversions.swift:64:12:64:32 | call to String.init(_:) | +| conversions.swift:66:18:66:30 | call to sourceFloat() | conversions.swift:66:12:66:31 | call to Float.init(_:) | +| conversions.swift:67:41:67:51 | call to sourceInt() | conversions.swift:67:12:67:70 | call to Float.init(sign:exponent:significand:) | +| conversions.swift:67:67:67:67 | 0.0 | conversions.swift:67:12:67:70 | call to Float.init(sign:exponent:significand:) | +| conversions.swift:68:41:68:41 | 0 | conversions.swift:68:12:68:70 | call to Float.init(sign:exponent:significand:) | +| conversions.swift:68:57:68:69 | call to sourceFloat() | conversions.swift:68:12:68:70 | call to Float.init(sign:exponent:significand:) | +| conversions.swift:69:54:69:54 | 0.0 | conversions.swift:69:12:69:57 | call to Float.init(signOf:magnitudeOf:) | +| conversions.swift:70:44:70:56 | call to sourceFloat() | conversions.swift:70:12:70:57 | call to Float.init(signOf:magnitudeOf:) | +| conversions.swift:72:12:72:24 | call to sourceFloat() | conversions.swift:72:12:72:26 | .exponent | +| conversions.swift:73:12:73:24 | call to sourceFloat() | conversions.swift:73:12:73:26 | .significand | | conversions.swift:78:19:78:32 | call to sourceString() | conversions.swift:78:12:78:33 | call to String.init(_:) | | conversions.swift:80:6:80:6 | SSA def(ms1) | conversions.swift:81:12:81:12 | ms1 | | conversions.swift:80:6:80:6 | ms1 | conversions.swift:80:6:80:6 | SSA def(ms1) | @@ -75,6 +100,7 @@ | conversions.swift:98:6:98:6 | v3 | conversions.swift:98:6:98:6 | SSA def(v3) | | conversions.swift:98:6:98:10 | ... as ... | conversions.swift:98:6:98:6 | v3 | | conversions.swift:98:25:98:69 | call to unsafeDowncast(_:to:) | conversions.swift:98:6:98:10 | ... as ... | +| conversions.swift:98:40:98:40 | parent | conversions.swift:98:25:98:69 | call to unsafeDowncast(_:to:) | | conversions.swift:99:12:99:12 | [post] v3 | conversions.swift:100:12:100:12 | v3 | | conversions.swift:99:12:99:12 | v3 | conversions.swift:100:12:100:12 | v3 | | simple.swift:12:13:12:13 | 1 | simple.swift:12:13:12:24 | ... .+(_:_:) ... | diff --git a/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected b/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected index 6923c1e8ec15..48ef4ada9256 100644 --- a/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected @@ -1,13 +1,46 @@ edges +| conversions.swift:25:16:25:26 | call to sourceInt() | conversions.swift:25:12:25:27 | call to Self.init(_:) | +| conversions.swift:26:18:26:28 | call to sourceInt() | conversions.swift:26:12:26:29 | call to Self.init(_:) | +| conversions.swift:27:18:27:28 | call to sourceInt() | conversions.swift:27:12:27:29 | call to Float.init(_:) | | conversions.swift:28:19:28:29 | call to sourceInt() | conversions.swift:28:12:28:30 | call to String.init(_:) | | conversions.swift:29:12:29:30 | call to String.init(_:) | conversions.swift:29:12:29:32 | .utf8 | | conversions.swift:29:19:29:29 | call to sourceInt() | conversions.swift:29:12:29:30 | call to String.init(_:) | +| conversions.swift:36:18:36:41 | call to numericCast(_:) | conversions.swift:37:12:37:12 | v2 | +| conversions.swift:36:30:36:40 | call to sourceInt() | conversions.swift:36:18:36:41 | call to numericCast(_:) | +| conversions.swift:39:17:39:57 | call to unsafeBitCast(_:to:) | conversions.swift:40:12:40:12 | v4 | +| conversions.swift:39:31:39:41 | call to sourceInt() | conversions.swift:39:17:39:57 | call to unsafeBitCast(_:to:) | +| conversions.swift:42:11:42:47 | call to Self.init(truncatingIfNeeded:) | conversions.swift:43:12:43:12 | v5 | +| conversions.swift:42:36:42:46 | call to sourceInt() | conversions.swift:42:11:42:47 | call to Self.init(truncatingIfNeeded:) | +| conversions.swift:45:11:45:39 | call to UInt.init(bitPattern:) | conversions.swift:46:12:46:12 | v6 | +| conversions.swift:45:28:45:38 | call to sourceInt() | conversions.swift:45:11:45:39 | call to UInt.init(bitPattern:) | +| conversions.swift:48:12:48:36 | call to Self.init(exactly:) [some:0] | conversions.swift:48:12:48:37 | ...! | +| conversions.swift:48:25:48:35 | call to sourceInt() | conversions.swift:48:12:48:36 | call to Self.init(exactly:) [some:0] | +| conversions.swift:49:26:49:36 | call to sourceInt() | conversions.swift:49:12:49:37 | call to Self.init(clamping:) | +| conversions.swift:50:36:50:46 | call to sourceInt() | conversions.swift:50:12:50:47 | call to Self.init(truncatingIfNeeded:) | +| conversions.swift:51:12:51:41 | call to Self.init(_:radix:) | conversions.swift:51:12:51:42 | ...! | +| conversions.swift:51:16:51:29 | call to sourceString() | conversions.swift:51:12:51:41 | call to Self.init(_:radix:) | +| conversions.swift:53:30:53:40 | call to sourceInt() | conversions.swift:53:12:53:41 | call to Self.init(littleEndian:) | +| conversions.swift:54:27:54:37 | call to sourceInt() | conversions.swift:54:12:54:38 | call to Self.init(bigEndian:) | +| conversions.swift:55:12:55:22 | call to sourceInt() | conversions.swift:55:12:55:24 | .littleEndian | +| conversions.swift:56:12:56:22 | call to sourceInt() | conversions.swift:56:12:56:24 | .bigEndian | +| conversions.swift:61:18:61:30 | call to sourceFloat() | conversions.swift:61:12:61:31 | call to Float.init(_:) | +| conversions.swift:62:18:62:30 | call to sourceFloat() | conversions.swift:62:12:62:31 | call to UInt8.init(_:) | | conversions.swift:63:19:63:31 | call to sourceFloat() | conversions.swift:63:12:63:32 | call to String.init(_:) | | conversions.swift:64:12:64:32 | call to String.init(_:) | conversions.swift:64:12:64:34 | .utf8 | | conversions.swift:64:19:64:31 | call to sourceFloat() | conversions.swift:64:12:64:32 | call to String.init(_:) | +| conversions.swift:66:18:66:30 | call to sourceFloat() | conversions.swift:66:12:66:31 | call to Float.init(_:) | +| conversions.swift:67:41:67:51 | call to sourceInt() | conversions.swift:67:12:67:70 | call to Float.init(sign:exponent:significand:) | +| conversions.swift:68:57:68:69 | call to sourceFloat() | conversions.swift:68:12:68:70 | call to Float.init(sign:exponent:significand:) | +| conversions.swift:70:44:70:56 | call to sourceFloat() | conversions.swift:70:12:70:57 | call to Float.init(signOf:magnitudeOf:) | +| conversions.swift:72:12:72:24 | call to sourceFloat() | conversions.swift:72:12:72:26 | .exponent | +| conversions.swift:73:12:73:24 | call to sourceFloat() | conversions.swift:73:12:73:26 | .significand | | conversions.swift:78:19:78:32 | call to sourceString() | conversions.swift:78:12:78:33 | call to String.init(_:) | | conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:95:12:95:12 | parent | | conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:96:12:96:12 | parent | +| conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:98:40:98:40 | parent | +| conversions.swift:98:25:98:69 | call to unsafeDowncast(_:to:) | conversions.swift:99:12:99:12 | v3 | +| conversions.swift:98:25:98:69 | call to unsafeDowncast(_:to:) | conversions.swift:100:12:100:12 | v3 | +| conversions.swift:98:40:98:40 | parent | conversions.swift:98:25:98:69 | call to unsafeDowncast(_:to:) | | file://:0:0:0:0 | self [first] | file://:0:0:0:0 | .first | | file://:0:0:0:0 | self [second] | file://:0:0:0:0 | .second | | file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [first] | @@ -87,23 +120,79 @@ edges | try.swift:18:18:18:25 | call to source() [some:0] | try.swift:18:13:18:25 | try? ... [some:0] | nodes | conversions.swift:24:12:24:22 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:25:12:25:27 | call to Self.init(_:) | semmle.label | call to Self.init(_:) | +| conversions.swift:25:16:25:26 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:26:12:26:29 | call to Self.init(_:) | semmle.label | call to Self.init(_:) | +| conversions.swift:26:18:26:28 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:27:12:27:29 | call to Float.init(_:) | semmle.label | call to Float.init(_:) | +| conversions.swift:27:18:27:28 | call to sourceInt() | semmle.label | call to sourceInt() | | conversions.swift:28:12:28:30 | call to String.init(_:) | semmle.label | call to String.init(_:) | | conversions.swift:28:19:28:29 | call to sourceInt() | semmle.label | call to sourceInt() | | conversions.swift:29:12:29:30 | call to String.init(_:) | semmle.label | call to String.init(_:) | | conversions.swift:29:12:29:32 | .utf8 | semmle.label | .utf8 | | conversions.swift:29:19:29:29 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:36:18:36:41 | call to numericCast(_:) | semmle.label | call to numericCast(_:) | +| conversions.swift:36:30:36:40 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:37:12:37:12 | v2 | semmle.label | v2 | +| conversions.swift:39:17:39:57 | call to unsafeBitCast(_:to:) | semmle.label | call to unsafeBitCast(_:to:) | +| conversions.swift:39:31:39:41 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:40:12:40:12 | v4 | semmle.label | v4 | +| conversions.swift:42:11:42:47 | call to Self.init(truncatingIfNeeded:) | semmle.label | call to Self.init(truncatingIfNeeded:) | +| conversions.swift:42:36:42:46 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:43:12:43:12 | v5 | semmle.label | v5 | +| conversions.swift:45:11:45:39 | call to UInt.init(bitPattern:) | semmle.label | call to UInt.init(bitPattern:) | +| conversions.swift:45:28:45:38 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:46:12:46:12 | v6 | semmle.label | v6 | +| conversions.swift:48:12:48:36 | call to Self.init(exactly:) [some:0] | semmle.label | call to Self.init(exactly:) [some:0] | +| conversions.swift:48:12:48:37 | ...! | semmle.label | ...! | +| conversions.swift:48:25:48:35 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:49:12:49:37 | call to Self.init(clamping:) | semmle.label | call to Self.init(clamping:) | +| conversions.swift:49:26:49:36 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:50:12:50:47 | call to Self.init(truncatingIfNeeded:) | semmle.label | call to Self.init(truncatingIfNeeded:) | +| conversions.swift:50:36:50:46 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:51:12:51:41 | call to Self.init(_:radix:) | semmle.label | call to Self.init(_:radix:) | +| conversions.swift:51:12:51:42 | ...! | semmle.label | ...! | +| conversions.swift:51:16:51:29 | call to sourceString() | semmle.label | call to sourceString() | +| conversions.swift:53:12:53:41 | call to Self.init(littleEndian:) | semmle.label | call to Self.init(littleEndian:) | +| conversions.swift:53:30:53:40 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:54:12:54:38 | call to Self.init(bigEndian:) | semmle.label | call to Self.init(bigEndian:) | +| conversions.swift:54:27:54:37 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:55:12:55:22 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:55:12:55:24 | .littleEndian | semmle.label | .littleEndian | +| conversions.swift:56:12:56:22 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:56:12:56:24 | .bigEndian | semmle.label | .bigEndian | | conversions.swift:60:12:60:24 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:61:12:61:31 | call to Float.init(_:) | semmle.label | call to Float.init(_:) | +| conversions.swift:61:18:61:30 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:62:12:62:31 | call to UInt8.init(_:) | semmle.label | call to UInt8.init(_:) | +| conversions.swift:62:18:62:30 | call to sourceFloat() | semmle.label | call to sourceFloat() | | conversions.swift:63:12:63:32 | call to String.init(_:) | semmle.label | call to String.init(_:) | | conversions.swift:63:19:63:31 | call to sourceFloat() | semmle.label | call to sourceFloat() | | conversions.swift:64:12:64:32 | call to String.init(_:) | semmle.label | call to String.init(_:) | | conversions.swift:64:12:64:34 | .utf8 | semmle.label | .utf8 | | conversions.swift:64:19:64:31 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:66:12:66:31 | call to Float.init(_:) | semmle.label | call to Float.init(_:) | +| conversions.swift:66:18:66:30 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:67:12:67:70 | call to Float.init(sign:exponent:significand:) | semmle.label | call to Float.init(sign:exponent:significand:) | +| conversions.swift:67:41:67:51 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:68:12:68:70 | call to Float.init(sign:exponent:significand:) | semmle.label | call to Float.init(sign:exponent:significand:) | +| conversions.swift:68:57:68:69 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:70:12:70:57 | call to Float.init(signOf:magnitudeOf:) | semmle.label | call to Float.init(signOf:magnitudeOf:) | +| conversions.swift:70:44:70:56 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:72:12:72:24 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:72:12:72:26 | .exponent | semmle.label | .exponent | +| conversions.swift:73:12:73:24 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:73:12:73:26 | .significand | semmle.label | .significand | | conversions.swift:77:12:77:25 | call to sourceString() | semmle.label | call to sourceString() | | conversions.swift:78:12:78:33 | call to String.init(_:) | semmle.label | call to String.init(_:) | | conversions.swift:78:19:78:32 | call to sourceString() | semmle.label | call to sourceString() | | conversions.swift:94:31:94:44 | call to sourceString() | semmle.label | call to sourceString() | | conversions.swift:95:12:95:12 | parent | semmle.label | parent | | conversions.swift:96:12:96:12 | parent | semmle.label | parent | +| conversions.swift:98:25:98:69 | call to unsafeDowncast(_:to:) | semmle.label | call to unsafeDowncast(_:to:) | +| conversions.swift:98:40:98:40 | parent | semmle.label | parent | +| conversions.swift:99:12:99:12 | v3 | semmle.label | v3 | +| conversions.swift:100:12:100:12 | v3 | semmle.label | v3 | | file://:0:0:0:0 | .first | semmle.label | .first | | file://:0:0:0:0 | .second | semmle.label | .second | | file://:0:0:0:0 | [post] self [first] | semmle.label | [post] self [first] | @@ -228,15 +317,40 @@ subpaths | stringinterpolation.swift:31:21:31:21 | p2 [second] | stringinterpolation.swift:7:6:7:6 | self [second] | file://:0:0:0:0 | .second | stringinterpolation.swift:31:21:31:24 | .second | #select | conversions.swift:24:12:24:22 | call to sourceInt() | conversions.swift:24:12:24:22 | call to sourceInt() | conversions.swift:24:12:24:22 | call to sourceInt() | result | +| conversions.swift:25:12:25:27 | call to Self.init(_:) | conversions.swift:25:16:25:26 | call to sourceInt() | conversions.swift:25:12:25:27 | call to Self.init(_:) | result | +| conversions.swift:26:12:26:29 | call to Self.init(_:) | conversions.swift:26:18:26:28 | call to sourceInt() | conversions.swift:26:12:26:29 | call to Self.init(_:) | result | +| conversions.swift:27:12:27:29 | call to Float.init(_:) | conversions.swift:27:18:27:28 | call to sourceInt() | conversions.swift:27:12:27:29 | call to Float.init(_:) | result | | conversions.swift:28:12:28:30 | call to String.init(_:) | conversions.swift:28:19:28:29 | call to sourceInt() | conversions.swift:28:12:28:30 | call to String.init(_:) | result | | conversions.swift:29:12:29:32 | .utf8 | conversions.swift:29:19:29:29 | call to sourceInt() | conversions.swift:29:12:29:32 | .utf8 | result | +| conversions.swift:37:12:37:12 | v2 | conversions.swift:36:30:36:40 | call to sourceInt() | conversions.swift:37:12:37:12 | v2 | result | +| conversions.swift:40:12:40:12 | v4 | conversions.swift:39:31:39:41 | call to sourceInt() | conversions.swift:40:12:40:12 | v4 | result | +| conversions.swift:43:12:43:12 | v5 | conversions.swift:42:36:42:46 | call to sourceInt() | conversions.swift:43:12:43:12 | v5 | result | +| conversions.swift:46:12:46:12 | v6 | conversions.swift:45:28:45:38 | call to sourceInt() | conversions.swift:46:12:46:12 | v6 | result | +| conversions.swift:48:12:48:37 | ...! | conversions.swift:48:25:48:35 | call to sourceInt() | conversions.swift:48:12:48:37 | ...! | result | +| conversions.swift:49:12:49:37 | call to Self.init(clamping:) | conversions.swift:49:26:49:36 | call to sourceInt() | conversions.swift:49:12:49:37 | call to Self.init(clamping:) | result | +| conversions.swift:50:12:50:47 | call to Self.init(truncatingIfNeeded:) | conversions.swift:50:36:50:46 | call to sourceInt() | conversions.swift:50:12:50:47 | call to Self.init(truncatingIfNeeded:) | result | +| conversions.swift:51:12:51:42 | ...! | conversions.swift:51:16:51:29 | call to sourceString() | conversions.swift:51:12:51:42 | ...! | result | +| conversions.swift:53:12:53:41 | call to Self.init(littleEndian:) | conversions.swift:53:30:53:40 | call to sourceInt() | conversions.swift:53:12:53:41 | call to Self.init(littleEndian:) | result | +| conversions.swift:54:12:54:38 | call to Self.init(bigEndian:) | conversions.swift:54:27:54:37 | call to sourceInt() | conversions.swift:54:12:54:38 | call to Self.init(bigEndian:) | result | +| conversions.swift:55:12:55:24 | .littleEndian | conversions.swift:55:12:55:22 | call to sourceInt() | conversions.swift:55:12:55:24 | .littleEndian | result | +| conversions.swift:56:12:56:24 | .bigEndian | conversions.swift:56:12:56:22 | call to sourceInt() | conversions.swift:56:12:56:24 | .bigEndian | result | | conversions.swift:60:12:60:24 | call to sourceFloat() | conversions.swift:60:12:60:24 | call to sourceFloat() | conversions.swift:60:12:60:24 | call to sourceFloat() | result | +| conversions.swift:61:12:61:31 | call to Float.init(_:) | conversions.swift:61:18:61:30 | call to sourceFloat() | conversions.swift:61:12:61:31 | call to Float.init(_:) | result | +| conversions.swift:62:12:62:31 | call to UInt8.init(_:) | conversions.swift:62:18:62:30 | call to sourceFloat() | conversions.swift:62:12:62:31 | call to UInt8.init(_:) | result | | conversions.swift:63:12:63:32 | call to String.init(_:) | conversions.swift:63:19:63:31 | call to sourceFloat() | conversions.swift:63:12:63:32 | call to String.init(_:) | result | | conversions.swift:64:12:64:34 | .utf8 | conversions.swift:64:19:64:31 | call to sourceFloat() | conversions.swift:64:12:64:34 | .utf8 | result | +| conversions.swift:66:12:66:31 | call to Float.init(_:) | conversions.swift:66:18:66:30 | call to sourceFloat() | conversions.swift:66:12:66:31 | call to Float.init(_:) | result | +| conversions.swift:67:12:67:70 | call to Float.init(sign:exponent:significand:) | conversions.swift:67:41:67:51 | call to sourceInt() | conversions.swift:67:12:67:70 | call to Float.init(sign:exponent:significand:) | result | +| conversions.swift:68:12:68:70 | call to Float.init(sign:exponent:significand:) | conversions.swift:68:57:68:69 | call to sourceFloat() | conversions.swift:68:12:68:70 | call to Float.init(sign:exponent:significand:) | result | +| conversions.swift:70:12:70:57 | call to Float.init(signOf:magnitudeOf:) | conversions.swift:70:44:70:56 | call to sourceFloat() | conversions.swift:70:12:70:57 | call to Float.init(signOf:magnitudeOf:) | result | +| conversions.swift:72:12:72:26 | .exponent | conversions.swift:72:12:72:24 | call to sourceFloat() | conversions.swift:72:12:72:26 | .exponent | result | +| conversions.swift:73:12:73:26 | .significand | conversions.swift:73:12:73:24 | call to sourceFloat() | conversions.swift:73:12:73:26 | .significand | result | | conversions.swift:77:12:77:25 | call to sourceString() | conversions.swift:77:12:77:25 | call to sourceString() | conversions.swift:77:12:77:25 | call to sourceString() | result | | conversions.swift:78:12:78:33 | call to String.init(_:) | conversions.swift:78:19:78:32 | call to sourceString() | conversions.swift:78:12:78:33 | call to String.init(_:) | result | | conversions.swift:95:12:95:12 | parent | conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:95:12:95:12 | parent | result | | conversions.swift:96:12:96:12 | parent | conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:96:12:96:12 | parent | result | +| conversions.swift:99:12:99:12 | v3 | conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:99:12:99:12 | v3 | result | +| conversions.swift:100:12:100:12 | v3 | conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:100:12:100:12 | v3 | result | | simple.swift:12:13:12:24 | ... .+(_:_:) ... | simple.swift:12:17:12:24 | call to source() | simple.swift:12:13:12:24 | ... .+(_:_:) ... | result | | simple.swift:13:13:13:24 | ... .+(_:_:) ... | simple.swift:13:13:13:20 | call to source() | simple.swift:13:13:13:24 | ... .+(_:_:) ... | result | | simple.swift:14:13:14:24 | ... .-(_:_:) ... | simple.swift:14:17:14:24 | call to source() | simple.swift:14:13:14:24 | ... .-(_:_:) ... | result | diff --git a/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift b/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift index 4789486ad456..a4d8956dff18 100644 --- a/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift +++ b/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift @@ -22,9 +22,9 @@ class MyString : LosslessStringConvertible, CustomStringConvertible, CustomDebug func testConversions() { sink(arg: sourceInt()) // $ tainted=24 - sink(arg: Int(sourceInt())) // $ MISSING: tainted= - sink(arg: UInt8(sourceInt())) // $ MISSING: tainted= - sink(arg: Float(sourceInt())) // $ MISSING: tainted= + sink(arg: Int(sourceInt())) // $ tainted=25 + sink(arg: UInt8(sourceInt())) // $ tainted=26 + sink(arg: Float(sourceInt())) // $ tainted=27 sink(arg: String(sourceInt())) // $ tainted=28 sink(arg: String(sourceInt()).utf8) // $ tainted=29 sink(arg: [UInt8](sourceString().utf8)) // $ MISSING: tainted= @@ -34,43 +34,43 @@ func testConversions() { } let v2: UInt8 = numericCast(sourceInt()) - sink(arg: v2) // $ MISSING: tainted= + sink(arg: v2) // $ tainted=36 let v4: UInt = unsafeBitCast(sourceInt(), to: UInt.self) - sink(arg: v4) // $ MISSING: tainted= + sink(arg: v4) // $ tainted=39 let v5 = UInt(truncatingIfNeeded: sourceInt()) - sink(arg: v5) // $ MISSING: tainted= + sink(arg: v5) // $ tainted=42 let v6 = UInt(bitPattern: sourceInt()) - sink(arg: v6) // $ MISSING: tainted= + sink(arg: v6) // $ tainted=45 - sink(arg: Int(exactly: sourceInt())!) // $ MISSING: tainted= - sink(arg: Int(clamping: sourceInt())) // $ MISSING: tainted= - sink(arg: Int(truncatingIfNeeded: sourceInt())) // $ MISSING: tainted= - sink(arg: Int(sourceString(), radix: 10)!) // $ MISSING: tainted= + sink(arg: Int(exactly: sourceInt())!) // $ tainted=48 + sink(arg: Int(clamping: sourceInt())) // $ tainted=49 + sink(arg: Int(truncatingIfNeeded: sourceInt())) // $ tainted=50 + sink(arg: Int(sourceString(), radix: 10)!) // $ tainted=51 - sink(arg: Int(littleEndian: sourceInt())) // $ MISSING: tainted= - sink(arg: Int(bigEndian: sourceInt())) // $ MISSING: tainted= - sink(arg: sourceInt().littleEndian) // $ MISSING: tainted= - sink(arg: sourceInt().bigEndian) // $ MISSING: tainted= + sink(arg: Int(littleEndian: sourceInt())) // $ tainted=53 + sink(arg: Int(bigEndian: sourceInt())) // $ tainted=54 + sink(arg: sourceInt().littleEndian) // $ tainted=55 + sink(arg: sourceInt().bigEndian) // $ tainted=56 // --- sink(arg: sourceFloat()) // $ tainted=60 - sink(arg: Float(sourceFloat())) // $ MISSING: tainted= - sink(arg: UInt8(sourceFloat())) // $ MISSING: tainted= + sink(arg: Float(sourceFloat())) // $ tainted=61 + sink(arg: UInt8(sourceFloat())) // $ tainted=62 sink(arg: String(sourceFloat())) // $ tainted=63 sink(arg: String(sourceFloat()).utf8) // $ tainted=64 - sink(arg: Float(sourceFloat())) // MISSING: tainted= - sink(arg: Float(sign: .plus, exponent: sourceInt(), significand: 0.0)) // MISSING: tainted= - sink(arg: Float(sign: .plus, exponent: 0, significand: sourceFloat())) // MISSING: tainted= + sink(arg: Float(sourceFloat())) // $ tainted=66 + sink(arg: Float(sign: .plus, exponent: sourceInt(), significand: 0.0)) // $ tainted=67 + sink(arg: Float(sign: .plus, exponent: 0, significand: sourceFloat())) // $ tainted=68 sink(arg: Float(signOf: sourceFloat(), magnitudeOf: 0.0)) // (good) - sink(arg: Float(signOf: 0.0, magnitudeOf: sourceFloat())) // MISSING: tainted= + sink(arg: Float(signOf: 0.0, magnitudeOf: sourceFloat())) // $ tainted=70 - sink(arg: sourceFloat().exponent) // $ MISSING: tainted= - sink(arg: sourceFloat().significand) // $ MISSING: tainted= + sink(arg: sourceFloat().exponent) // $ tainted=72 + sink(arg: sourceFloat().significand) // $ tainted=73 // --- @@ -96,6 +96,6 @@ func testConversions() { sink(arg: parent as! MyChildClass) // $ tainted=94 let v3: MyChildClass = unsafeDowncast(parent, to: MyChildClass.self) - sink(arg: v3) // $ MISSING: tainted= - sink(arg: v3 as! MyParentClass) // $ MISSING: tainted= + sink(arg: v3) // $ tainted=94 + sink(arg: v3 as! MyParentClass) // $ tainted=94 } From effe3762b8cf0cbcd326d742bd885655d0197538 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 9 Aug 2023 17:25:56 +0100 Subject: [PATCH 03/20] Swift: More robust OptionalSomePattern flow. --- .../lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll | 5 +++++ .../library-tests/dataflow/taint/core/LocalTaint.expected | 1 + .../ql/test/library-tests/dataflow/taint/core/Taint.expected | 4 ++++ .../test/library-tests/dataflow/taint/core/conversions.swift | 2 +- 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index 145ac20573b3..0ddd5728e52c 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -182,6 +182,11 @@ private module Cached { // retaining this case increases robustness of flow). nodeFrom.asExpr() = nodeTo.asExpr().(ForceValueExpr).getSubExpr() or + // read of an optional .some member via `let x: T = y: T?` pattern matching + // note: similar to `ForceValueExpr` this is ideally a content `readStep` but + // in practice we sometimes have taint on the optional itself. + nodeTo.asPattern() = nodeFrom.asPattern().(OptionalSomePattern).getSubPattern() + or // flow through `?` and `?.` nodeFrom.asExpr() = nodeTo.asExpr().(BindOptionalExpr).getSubExpr() or diff --git a/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected b/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected index 1ff797add875..40862be951dc 100644 --- a/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected @@ -23,6 +23,7 @@ | conversions.swift:29:12:29:30 | call to String.init(_:) | conversions.swift:29:12:29:32 | .utf8 | | conversions.swift:29:19:29:29 | call to sourceInt() | conversions.swift:29:12:29:30 | call to String.init(_:) | | conversions.swift:30:20:30:33 | call to sourceString() | conversions.swift:30:20:30:35 | .utf8 | +| conversions.swift:32:5:32:9 | let ...? | conversions.swift:32:9:32:9 | v | | conversions.swift:32:9:32:9 | SSA def(v) | conversions.swift:33:13:33:13 | v | | conversions.swift:32:9:32:9 | v | conversions.swift:32:9:32:9 | SSA def(v) | | conversions.swift:32:13:32:23 | call to sourceInt() | conversions.swift:32:5:32:9 | let ...? | diff --git a/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected b/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected index 48ef4ada9256..e2c7100da5c9 100644 --- a/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected @@ -5,6 +5,7 @@ edges | conversions.swift:28:19:28:29 | call to sourceInt() | conversions.swift:28:12:28:30 | call to String.init(_:) | | conversions.swift:29:12:29:30 | call to String.init(_:) | conversions.swift:29:12:29:32 | .utf8 | | conversions.swift:29:19:29:29 | call to sourceInt() | conversions.swift:29:12:29:30 | call to String.init(_:) | +| conversions.swift:32:13:32:23 | call to sourceInt() | conversions.swift:33:13:33:13 | v | | conversions.swift:36:18:36:41 | call to numericCast(_:) | conversions.swift:37:12:37:12 | v2 | | conversions.swift:36:30:36:40 | call to sourceInt() | conversions.swift:36:18:36:41 | call to numericCast(_:) | | conversions.swift:39:17:39:57 | call to unsafeBitCast(_:to:) | conversions.swift:40:12:40:12 | v4 | @@ -131,6 +132,8 @@ nodes | conversions.swift:29:12:29:30 | call to String.init(_:) | semmle.label | call to String.init(_:) | | conversions.swift:29:12:29:32 | .utf8 | semmle.label | .utf8 | | conversions.swift:29:19:29:29 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:32:13:32:23 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:33:13:33:13 | v | semmle.label | v | | conversions.swift:36:18:36:41 | call to numericCast(_:) | semmle.label | call to numericCast(_:) | | conversions.swift:36:30:36:40 | call to sourceInt() | semmle.label | call to sourceInt() | | conversions.swift:37:12:37:12 | v2 | semmle.label | v2 | @@ -322,6 +325,7 @@ subpaths | conversions.swift:27:12:27:29 | call to Float.init(_:) | conversions.swift:27:18:27:28 | call to sourceInt() | conversions.swift:27:12:27:29 | call to Float.init(_:) | result | | conversions.swift:28:12:28:30 | call to String.init(_:) | conversions.swift:28:19:28:29 | call to sourceInt() | conversions.swift:28:12:28:30 | call to String.init(_:) | result | | conversions.swift:29:12:29:32 | .utf8 | conversions.swift:29:19:29:29 | call to sourceInt() | conversions.swift:29:12:29:32 | .utf8 | result | +| conversions.swift:33:13:33:13 | v | conversions.swift:32:13:32:23 | call to sourceInt() | conversions.swift:33:13:33:13 | v | result | | conversions.swift:37:12:37:12 | v2 | conversions.swift:36:30:36:40 | call to sourceInt() | conversions.swift:37:12:37:12 | v2 | result | | conversions.swift:40:12:40:12 | v4 | conversions.swift:39:31:39:41 | call to sourceInt() | conversions.swift:40:12:40:12 | v4 | result | | conversions.swift:43:12:43:12 | v5 | conversions.swift:42:36:42:46 | call to sourceInt() | conversions.swift:43:12:43:12 | v5 | result | diff --git a/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift b/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift index a4d8956dff18..b9a7ad6ad5c5 100644 --- a/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift +++ b/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift @@ -30,7 +30,7 @@ func testConversions() { sink(arg: [UInt8](sourceString().utf8)) // $ MISSING: tainted= if let v = sourceInt() as? UInt { - sink(arg: v) // $ MISSING: tainted= + sink(arg: v) // $ tainted=32 } let v2: UInt8 = numericCast(sourceInt()) From 376479325de840bb4665994256ccb936fcd3f9ba Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 10 Aug 2023 09:27:05 +0100 Subject: [PATCH 04/20] Swift: Model LosslessStringConvertible. --- .../swift/frameworks/StandardLibrary/String.qll | 5 +++-- .../dataflow/taint/core/LocalTaint.expected | 3 +++ .../library-tests/dataflow/taint/core/Taint.expected | 11 +++++++++++ .../dataflow/taint/core/conversions.swift | 2 +- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/String.qll b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/String.qll index 4768521322ff..65b1f23ad944 100644 --- a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/String.qll +++ b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/String.qll @@ -27,7 +27,7 @@ private class StringSource extends SourceModelCsv { } /** - * A model for `String` and `StringProtocol` members that permit taint flow. + * A model for members of `String`, `StringProtocol` and similar classes that permit taint flow. */ private class StringSummaries extends SummaryModelCsv { override predicate row(string row) { @@ -111,7 +111,8 @@ private class StringSummaries extends SummaryModelCsv { ";String;true;randomElement();;;Argument[-1];ReturnValue;taint", ";String;true;randomElement(using:);;;Argument[-1];ReturnValue;taint", ";String;true;enumerated();;;Argument[-1];ReturnValue;taint", - ";String;true;encode(to:);;;Argument[-1];Argument[0];taint" + ";String;true;encode(to:);;;Argument[-1];Argument[0];taint", + ";LosslessStringConvertible;true;init(_:);;;Argument[0];ReturnValue;taint", ] } } diff --git a/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected b/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected index 40862be951dc..6fd724f31ad8 100644 --- a/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected @@ -10,6 +10,7 @@ | conversions.swift:15:7:15:7 | self | conversions.swift:15:7:15:7 | SSA def(self) | | conversions.swift:16:11:16:11 | SSA def(self) | conversions.swift:16:11:16:42 | self[return] | | conversions.swift:16:11:16:11 | self | conversions.swift:16:11:16:11 | SSA def(self) | +| conversions.swift:16:11:16:42 | [summary param] 0 in MyString.init(_:) | conversions.swift:16:11:16:42 | [summary] to write: ReturnValue in MyString.init(_:) | | conversions.swift:18:28:18:28 | SSA def(self) | conversions.swift:18:28:18:44 | self[return] | | conversions.swift:18:28:18:28 | self | conversions.swift:18:28:18:28 | SSA def(self) | | conversions.swift:19:33:19:33 | SSA def(self) | conversions.swift:19:33:19:49 | self[return] | @@ -73,6 +74,7 @@ | conversions.swift:80:6:80:6 | ms1 | conversions.swift:80:6:80:6 | SSA def(ms1) | | conversions.swift:80:12:80:26 | call to MyString.init(_:) | conversions.swift:80:12:80:27 | ...! | | conversions.swift:80:12:80:27 | ...! | conversions.swift:80:6:80:6 | ms1 | +| conversions.swift:80:21:80:21 | abc | conversions.swift:80:12:80:26 | call to MyString.init(_:) | | conversions.swift:81:12:81:12 | [post] ms1 | conversions.swift:82:12:82:12 | ms1 | | conversions.swift:81:12:81:12 | ms1 | conversions.swift:82:12:82:12 | ms1 | | conversions.swift:82:12:82:12 | [post] ms1 | conversions.swift:83:12:83:12 | ms1 | @@ -83,6 +85,7 @@ | conversions.swift:86:6:86:6 | ms2 | conversions.swift:86:6:86:6 | SSA def(ms2) | | conversions.swift:86:12:86:35 | call to MyString.init(_:) | conversions.swift:86:12:86:36 | ...! | | conversions.swift:86:12:86:36 | ...! | conversions.swift:86:6:86:6 | ms2 | +| conversions.swift:86:21:86:34 | call to sourceString() | conversions.swift:86:12:86:35 | call to MyString.init(_:) | | conversions.swift:87:12:87:12 | [post] ms2 | conversions.swift:88:12:88:12 | ms2 | | conversions.swift:87:12:87:12 | ms2 | conversions.swift:88:12:88:12 | ms2 | | conversions.swift:88:12:88:12 | [post] ms2 | conversions.swift:89:12:89:12 | ms2 | diff --git a/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected b/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected index e2c7100da5c9..25b8d79aa68e 100644 --- a/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected @@ -36,6 +36,11 @@ edges | conversions.swift:72:12:72:24 | call to sourceFloat() | conversions.swift:72:12:72:26 | .exponent | | conversions.swift:73:12:73:24 | call to sourceFloat() | conversions.swift:73:12:73:26 | .significand | | conversions.swift:78:19:78:32 | call to sourceString() | conversions.swift:78:12:78:33 | call to String.init(_:) | +| conversions.swift:86:12:86:35 | call to MyString.init(_:) | conversions.swift:86:12:86:35 | call to MyString.init(_:) [some:0] | +| conversions.swift:86:12:86:35 | call to MyString.init(_:) | conversions.swift:87:12:87:12 | ms2 | +| conversions.swift:86:12:86:35 | call to MyString.init(_:) [some:0] | conversions.swift:86:12:86:36 | ...! | +| conversions.swift:86:12:86:36 | ...! | conversions.swift:87:12:87:12 | ms2 | +| conversions.swift:86:21:86:34 | call to sourceString() | conversions.swift:86:12:86:35 | call to MyString.init(_:) | | conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:95:12:95:12 | parent | | conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:96:12:96:12 | parent | | conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:98:40:98:40 | parent | @@ -189,6 +194,11 @@ nodes | conversions.swift:77:12:77:25 | call to sourceString() | semmle.label | call to sourceString() | | conversions.swift:78:12:78:33 | call to String.init(_:) | semmle.label | call to String.init(_:) | | conversions.swift:78:19:78:32 | call to sourceString() | semmle.label | call to sourceString() | +| conversions.swift:86:12:86:35 | call to MyString.init(_:) | semmle.label | call to MyString.init(_:) | +| conversions.swift:86:12:86:35 | call to MyString.init(_:) [some:0] | semmle.label | call to MyString.init(_:) [some:0] | +| conversions.swift:86:12:86:36 | ...! | semmle.label | ...! | +| conversions.swift:86:21:86:34 | call to sourceString() | semmle.label | call to sourceString() | +| conversions.swift:87:12:87:12 | ms2 | semmle.label | ms2 | | conversions.swift:94:31:94:44 | call to sourceString() | semmle.label | call to sourceString() | | conversions.swift:95:12:95:12 | parent | semmle.label | parent | | conversions.swift:96:12:96:12 | parent | semmle.label | parent | @@ -351,6 +361,7 @@ subpaths | conversions.swift:73:12:73:26 | .significand | conversions.swift:73:12:73:24 | call to sourceFloat() | conversions.swift:73:12:73:26 | .significand | result | | conversions.swift:77:12:77:25 | call to sourceString() | conversions.swift:77:12:77:25 | call to sourceString() | conversions.swift:77:12:77:25 | call to sourceString() | result | | conversions.swift:78:12:78:33 | call to String.init(_:) | conversions.swift:78:19:78:32 | call to sourceString() | conversions.swift:78:12:78:33 | call to String.init(_:) | result | +| conversions.swift:87:12:87:12 | ms2 | conversions.swift:86:21:86:34 | call to sourceString() | conversions.swift:87:12:87:12 | ms2 | result | | conversions.swift:95:12:95:12 | parent | conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:95:12:95:12 | parent | result | | conversions.swift:96:12:96:12 | parent | conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:96:12:96:12 | parent | result | | conversions.swift:99:12:99:12 | v3 | conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:99:12:99:12 | v3 | result | diff --git a/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift b/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift index b9a7ad6ad5c5..499ec8dcfe25 100644 --- a/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift +++ b/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift @@ -84,7 +84,7 @@ func testConversions() { sink(arg: ms1.clean) let ms2 = MyString(sourceString())! - sink(arg: ms2) // $ MISSING: tainted= + sink(arg: ms2) // $ tainted=86 sink(arg: ms2.description) // $ MISSING: tainted= sink(arg: ms2.debugDescription) // $ MISSING: tainted= sink(arg: ms2.clean) From 936b1ced4d9bbc3c4404e6bbfe0b28d8f9de3102 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 10 Aug 2023 19:24:30 +0100 Subject: [PATCH 05/20] Swift: Add one last test case (and address a .expected change elsewhere). --- .../library-tests/dataflow/taint/core/conversions.swift | 8 ++++++++ .../library-tests/dataflow/taint/libraries/string.swift | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift b/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift index 499ec8dcfe25..321c555e0abc 100644 --- a/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift +++ b/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift @@ -99,3 +99,11 @@ func testConversions() { sink(arg: v3) // $ tainted=94 sink(arg: v3 as! MyParentClass) // $ tainted=94 } + +var myCEnumConst : Int = 0 +typealias MyCEnumType = UInt32 + +func testCEnum() { + sink(arg: MyCEnumType(myCEnumConst)) + sink(arg: MyCEnumType(sourceInt())) // $ tainted=108 +} diff --git a/swift/ql/test/library-tests/dataflow/taint/libraries/string.swift b/swift/ql/test/library-tests/dataflow/taint/libraries/string.swift index 9f684139fd30..919a07b66758 100644 --- a/swift/ql/test/library-tests/dataflow/taint/libraries/string.swift +++ b/swift/ql/test/library-tests/dataflow/taint/libraries/string.swift @@ -589,7 +589,7 @@ func taintedThroughConversion() { sink(arg: String(describing: source())) // $ tainted=589 sink(arg: Int("123")!) - sink(arg: Int(source2())!) // $ MISSING: tainted=592 + sink(arg: Int(source2())!) // $ tainted=592 } func untaintedFields() { From 4f5d7e1b6f33ca95a2a0a69bbca84a7ac275ccd9 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 10 Aug 2023 19:49:27 +0100 Subject: [PATCH 06/20] Swift: Accept test changes. --- .../dataflow/dataflow/DataFlow.expected | 31 +++++++++++++++++++ .../dataflow/dataflow/LocalFlow.expected | 11 +++++++ .../dataflow/taint/core/LocalTaint.expected | 2 ++ .../dataflow/taint/core/Taint.expected | 4 +++ 4 files changed, 48 insertions(+) diff --git a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected index b0404de37ec5..77530c3af288 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected @@ -6,9 +6,11 @@ edges | file://:0:0:0:0 | self [v3] | file://:0:0:0:0 | .v3 | | file://:0:0:0:0 | self [x, some:0] | file://:0:0:0:0 | .x [some:0] | | file://:0:0:0:0 | self [x] | file://:0:0:0:0 | .x | +| file://:0:0:0:0 | self [x] | file://:0:0:0:0 | .x | | file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [v2] | | file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [v3] | | file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [x] | +| file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [x] | | file://:0:0:0:0 | value [some:0] | file://:0:0:0:0 | [post] self [v2, some:0] | | file://:0:0:0:0 | value [some:0] | file://:0:0:0:0 | [post] self [x, some:0] | | test.swift:6:19:6:26 | call to source() | test.swift:7:15:7:15 | t1 | @@ -109,6 +111,8 @@ edges | test.swift:225:14:225:21 | call to source() | test.swift:238:13:238:15 | .source_value | | test.swift:259:12:259:19 | call to source() | test.swift:259:12:259:19 | call to source() [some:0] | | test.swift:259:12:259:19 | call to source() | test.swift:263:13:263:28 | call to optionalSource() | +| test.swift:259:12:259:19 | call to source() | test.swift:517:13:517:28 | call to optionalSource() | +| test.swift:259:12:259:19 | call to source() | test.swift:544:13:544:28 | call to optionalSource() | | test.swift:259:12:259:19 | call to source() [some:0] | test.swift:263:13:263:28 | call to optionalSource() [some:0] | | test.swift:259:12:259:19 | call to source() [some:0] | test.swift:517:13:517:28 | call to optionalSource() [some:0] | | test.swift:259:12:259:19 | call to source() [some:0] | test.swift:544:13:544:28 | call to optionalSource() [some:0] | @@ -119,7 +123,9 @@ edges | test.swift:263:13:263:28 | call to optionalSource() | test.swift:275:15:275:27 | ... ??(_:_:) ... | | test.swift:263:13:263:28 | call to optionalSource() | test.swift:279:15:279:31 | ... ? ... : ... | | test.swift:263:13:263:28 | call to optionalSource() | test.swift:280:15:280:38 | ... ? ... : ... | +| test.swift:263:13:263:28 | call to optionalSource() | test.swift:285:19:285:19 | z | | test.swift:263:13:263:28 | call to optionalSource() | test.swift:291:16:291:17 | ...? | +| test.swift:263:13:263:28 | call to optionalSource() | test.swift:300:15:300:15 | z1 | | test.swift:263:13:263:28 | call to optionalSource() | test.swift:303:15:303:16 | ...! | | test.swift:263:13:263:28 | call to optionalSource() [some:0] | test.swift:267:15:267:15 | x [some:0] | | test.swift:263:13:263:28 | call to optionalSource() [some:0] | test.swift:279:26:279:26 | x [some:0] | @@ -147,6 +153,7 @@ edges | test.swift:291:16:291:17 | ...? | test.swift:291:16:291:26 | call to signum() | | test.swift:291:16:291:17 | ...? [some:0] | test.swift:291:16:291:26 | call to signum() [some:0] | | test.swift:291:16:291:26 | call to signum() | test.swift:291:16:291:26 | call to signum() [some:0] | +| test.swift:291:16:291:26 | call to signum() | test.swift:292:19:292:19 | z | | test.swift:291:16:291:26 | call to signum() [some:0] | test.swift:291:8:291:12 | let ...? [some:0] | | test.swift:298:11:298:15 | let ...? [some:0] | test.swift:298:15:298:15 | z1 | | test.swift:298:15:298:15 | z1 | test.swift:300:15:300:15 | z1 | @@ -246,6 +253,7 @@ edges | test.swift:507:15:507:15 | e2 [some:0] | test.swift:507:15:507:17 | ...! | | test.swift:509:15:509:15 | e4 [some:0] | test.swift:509:15:509:17 | ...! | | test.swift:511:15:511:15 | e6 [some:0] | test.swift:511:15:511:17 | ...! | +| test.swift:517:13:517:28 | call to optionalSource() | test.swift:520:19:520:19 | a | | test.swift:517:13:517:28 | call to optionalSource() [some:0] | test.swift:519:8:519:12 | let ...? [some:0] | | test.swift:517:13:517:28 | call to optionalSource() [some:0] | test.swift:524:19:524:19 | x [some:0] | | test.swift:519:8:519:12 | let ...? [some:0] | test.swift:519:12:519:12 | a | @@ -256,15 +264,24 @@ edges | test.swift:526:11:526:22 | .some(...) [some:0] | test.swift:526:21:526:21 | a | | test.swift:526:21:526:21 | a | test.swift:527:19:527:19 | a | | test.swift:540:9:540:9 | self [x, some:0] | file://:0:0:0:0 | self [x, some:0] | +| test.swift:540:9:540:9 | self [x] | file://:0:0:0:0 | self [x] | +| test.swift:540:9:540:9 | value | file://:0:0:0:0 | value | | test.swift:540:9:540:9 | value [some:0] | file://:0:0:0:0 | value [some:0] | +| test.swift:544:13:544:28 | call to optionalSource() | test.swift:546:12:546:12 | x | | test.swift:544:13:544:28 | call to optionalSource() [some:0] | test.swift:546:12:546:12 | x [some:0] | | test.swift:546:5:546:5 | [post] cx [x, some:0] | test.swift:550:20:550:20 | cx [x, some:0] | +| test.swift:546:5:546:5 | [post] cx [x] | test.swift:550:20:550:20 | cx [x] | +| test.swift:546:12:546:12 | x | test.swift:540:9:540:9 | value | +| test.swift:546:12:546:12 | x | test.swift:546:5:546:5 | [post] cx [x] | | test.swift:546:12:546:12 | x [some:0] | test.swift:540:9:540:9 | value [some:0] | | test.swift:546:12:546:12 | x [some:0] | test.swift:546:5:546:5 | [post] cx [x, some:0] | | test.swift:550:11:550:15 | let ...? [some:0] | test.swift:550:15:550:15 | z1 | | test.swift:550:15:550:15 | z1 | test.swift:551:15:551:15 | z1 | | test.swift:550:20:550:20 | cx [x, some:0] | test.swift:540:9:540:9 | self [x, some:0] | | test.swift:550:20:550:20 | cx [x, some:0] | test.swift:550:20:550:23 | .x [some:0] | +| test.swift:550:20:550:20 | cx [x] | test.swift:540:9:540:9 | self [x] | +| test.swift:550:20:550:20 | cx [x] | test.swift:550:20:550:23 | .x | +| test.swift:550:20:550:23 | .x | test.swift:551:15:551:15 | z1 | | test.swift:550:20:550:23 | .x [some:0] | test.swift:550:11:550:15 | let ...? [some:0] | | test.swift:557:14:557:21 | call to source() | test.swift:557:13:557:21 | call to +(_:) | | test.swift:566:9:566:9 | self [str] | file://:0:0:0:0 | self [str] | @@ -396,12 +413,14 @@ nodes | file://:0:0:0:0 | .v2 [some:0] | semmle.label | .v2 [some:0] | | file://:0:0:0:0 | .v3 | semmle.label | .v3 | | file://:0:0:0:0 | .x | semmle.label | .x | +| file://:0:0:0:0 | .x | semmle.label | .x | | file://:0:0:0:0 | .x [some:0] | semmle.label | .x [some:0] | | file://:0:0:0:0 | [post] self [v2, some:0] | semmle.label | [post] self [v2, some:0] | | file://:0:0:0:0 | [post] self [v2] | semmle.label | [post] self [v2] | | file://:0:0:0:0 | [post] self [v3] | semmle.label | [post] self [v3] | | file://:0:0:0:0 | [post] self [x, some:0] | semmle.label | [post] self [x, some:0] | | file://:0:0:0:0 | [post] self [x] | semmle.label | [post] self [x] | +| file://:0:0:0:0 | [post] self [x] | semmle.label | [post] self [x] | | file://:0:0:0:0 | self [a, x] | semmle.label | self [a, x] | | file://:0:0:0:0 | self [str] | semmle.label | self [str] | | file://:0:0:0:0 | self [v2, some:0] | semmle.label | self [v2, some:0] | @@ -409,6 +428,8 @@ nodes | file://:0:0:0:0 | self [v3] | semmle.label | self [v3] | | file://:0:0:0:0 | self [x, some:0] | semmle.label | self [x, some:0] | | file://:0:0:0:0 | self [x] | semmle.label | self [x] | +| file://:0:0:0:0 | self [x] | semmle.label | self [x] | +| file://:0:0:0:0 | value | semmle.label | value | | file://:0:0:0:0 | value | semmle.label | value | | file://:0:0:0:0 | value | semmle.label | value | | file://:0:0:0:0 | value | semmle.label | value | @@ -665,6 +686,7 @@ nodes | test.swift:509:15:509:17 | ...! | semmle.label | ...! | | test.swift:511:15:511:15 | e6 [some:0] | semmle.label | e6 [some:0] | | test.swift:511:15:511:17 | ...! | semmle.label | ...! | +| test.swift:517:13:517:28 | call to optionalSource() | semmle.label | call to optionalSource() | | test.swift:517:13:517:28 | call to optionalSource() [some:0] | semmle.label | call to optionalSource() [some:0] | | test.swift:519:8:519:12 | let ...? [some:0] | semmle.label | let ...? [some:0] | | test.swift:519:12:519:12 | a | semmle.label | a | @@ -676,13 +698,20 @@ nodes | test.swift:526:21:526:21 | a | semmle.label | a | | test.swift:527:19:527:19 | a | semmle.label | a | | test.swift:540:9:540:9 | self [x, some:0] | semmle.label | self [x, some:0] | +| test.swift:540:9:540:9 | self [x] | semmle.label | self [x] | +| test.swift:540:9:540:9 | value | semmle.label | value | | test.swift:540:9:540:9 | value [some:0] | semmle.label | value [some:0] | +| test.swift:544:13:544:28 | call to optionalSource() | semmle.label | call to optionalSource() | | test.swift:544:13:544:28 | call to optionalSource() [some:0] | semmle.label | call to optionalSource() [some:0] | | test.swift:546:5:546:5 | [post] cx [x, some:0] | semmle.label | [post] cx [x, some:0] | +| test.swift:546:5:546:5 | [post] cx [x] | semmle.label | [post] cx [x] | +| test.swift:546:12:546:12 | x | semmle.label | x | | test.swift:546:12:546:12 | x [some:0] | semmle.label | x [some:0] | | test.swift:550:11:550:15 | let ...? [some:0] | semmle.label | let ...? [some:0] | | test.swift:550:15:550:15 | z1 | semmle.label | z1 | | test.swift:550:20:550:20 | cx [x, some:0] | semmle.label | cx [x, some:0] | +| test.swift:550:20:550:20 | cx [x] | semmle.label | cx [x] | +| test.swift:550:20:550:23 | .x | semmle.label | .x | | test.swift:550:20:550:23 | .x [some:0] | semmle.label | .x [some:0] | | test.swift:551:15:551:15 | z1 | semmle.label | z1 | | test.swift:557:13:557:21 | call to +(_:) | semmle.label | call to +(_:) | @@ -846,8 +875,10 @@ subpaths | test.swift:219:13:219:15 | .a [x] | test.swift:163:7:163:7 | self [x] | file://:0:0:0:0 | .x | test.swift:219:13:219:17 | .x | | test.swift:490:24:490:31 | call to source() | test.swift:375:16:375:21 | v | test.swift:375:45:375:62 | call to ... [mySingle:0] | test.swift:490:14:490:32 | call to mkMyEnum1(_:) [mySingle:0] | | test.swift:503:26:503:33 | call to source() | test.swift:377:18:377:23 | v | test.swift:377:45:377:60 | call to ... [some:0] | test.swift:503:14:503:34 | call to mkOptional1(_:) [some:0] | +| test.swift:546:12:546:12 | x | test.swift:540:9:540:9 | value | file://:0:0:0:0 | [post] self [x] | test.swift:546:5:546:5 | [post] cx [x] | | test.swift:546:12:546:12 | x [some:0] | test.swift:540:9:540:9 | value [some:0] | file://:0:0:0:0 | [post] self [x, some:0] | test.swift:546:5:546:5 | [post] cx [x, some:0] | | test.swift:550:20:550:20 | cx [x, some:0] | test.swift:540:9:540:9 | self [x, some:0] | file://:0:0:0:0 | .x [some:0] | test.swift:550:20:550:23 | .x [some:0] | +| test.swift:550:20:550:20 | cx [x] | test.swift:540:9:540:9 | self [x] | file://:0:0:0:0 | .x | test.swift:550:20:550:23 | .x | | test.swift:574:20:574:28 | call to source3() | test.swift:567:10:567:13 | s | test.swift:568:7:568:7 | [post] self [str] | test.swift:574:7:574:7 | [post] self [str] | | test.swift:580:13:580:33 | call to MyClass.init(s:) [str] | test.swift:566:9:566:9 | self [str] | file://:0:0:0:0 | .str | test.swift:580:13:580:35 | .str | | test.swift:580:24:580:32 | call to source3() | test.swift:567:10:567:13 | s | test.swift:567:5:569:5 | self[return] [str] | test.swift:580:13:580:33 | call to MyClass.init(s:) [str] | diff --git a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected index 6058e6e645b7..b583c64cdca1 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected @@ -281,30 +281,36 @@ | test.swift:282:26:282:26 | y | test.swift:287:16:287:16 | y | | test.swift:282:26:282:27 | ...! | test.swift:282:15:282:38 | ... ? ... : ... | | test.swift:282:31:282:38 | call to source() | test.swift:282:15:282:38 | ... ? ... : ... | +| test.swift:284:8:284:12 | let ...? | test.swift:284:12:284:12 | z | | test.swift:284:12:284:12 | SSA def(z) | test.swift:285:19:285:19 | z | | test.swift:284:12:284:12 | z | test.swift:284:12:284:12 | SSA def(z) | | test.swift:284:16:284:16 | x | test.swift:284:8:284:12 | let ...? | | test.swift:284:16:284:16 | x | test.swift:291:16:291:16 | x | +| test.swift:287:8:287:12 | let ...? | test.swift:287:12:287:12 | z | | test.swift:287:12:287:12 | SSA def(z) | test.swift:288:19:288:19 | z | | test.swift:287:12:287:12 | z | test.swift:287:12:287:12 | SSA def(z) | | test.swift:287:16:287:16 | y | test.swift:287:8:287:12 | let ...? | | test.swift:287:16:287:16 | y | test.swift:294:16:294:16 | y | +| test.swift:291:8:291:12 | let ...? | test.swift:291:12:291:12 | z | | test.swift:291:12:291:12 | SSA def(z) | test.swift:292:19:292:19 | z | | test.swift:291:12:291:12 | z | test.swift:291:12:291:12 | SSA def(z) | | test.swift:291:16:291:16 | x | test.swift:291:16:291:17 | ...? | | test.swift:291:16:291:16 | x | test.swift:298:20:298:20 | x | | test.swift:291:16:291:26 | OptionalEvaluationExpr | test.swift:291:8:291:12 | let ...? | | test.swift:291:16:291:26 | call to signum() | test.swift:291:16:291:26 | OptionalEvaluationExpr | +| test.swift:294:8:294:12 | let ...? | test.swift:294:12:294:12 | z | | test.swift:294:12:294:12 | SSA def(z) | test.swift:295:19:295:19 | z | | test.swift:294:12:294:12 | z | test.swift:294:12:294:12 | SSA def(z) | | test.swift:294:16:294:16 | y | test.swift:294:16:294:17 | ...? | | test.swift:294:16:294:16 | y | test.swift:299:20:299:20 | y | | test.swift:294:16:294:26 | OptionalEvaluationExpr | test.swift:294:8:294:12 | let ...? | | test.swift:294:16:294:26 | call to signum() | test.swift:294:16:294:26 | OptionalEvaluationExpr | +| test.swift:298:11:298:15 | let ...? | test.swift:298:15:298:15 | z1 | | test.swift:298:15:298:15 | SSA def(z1) | test.swift:300:15:300:15 | z1 | | test.swift:298:15:298:15 | z1 | test.swift:298:15:298:15 | SSA def(z1) | | test.swift:298:20:298:20 | x | test.swift:298:11:298:15 | let ...? | | test.swift:298:20:298:20 | x | test.swift:303:15:303:15 | x | +| test.swift:299:11:299:15 | let ...? | test.swift:299:15:299:15 | z2 | | test.swift:299:15:299:15 | SSA def(z2) | test.swift:301:15:301:15 | z2 | | test.swift:299:15:299:15 | z2 | test.swift:299:15:299:15 | SSA def(z2) | | test.swift:299:20:299:20 | y | test.swift:299:11:299:15 | let ...? | @@ -582,10 +588,12 @@ | test.swift:517:9:517:9 | SSA def(x) | test.swift:519:16:519:16 | x | | test.swift:517:9:517:9 | x | test.swift:517:9:517:9 | SSA def(x) | | test.swift:517:13:517:28 | call to optionalSource() | test.swift:517:9:517:9 | x | +| test.swift:519:8:519:12 | let ...? | test.swift:519:12:519:12 | a | | test.swift:519:12:519:12 | SSA def(a) | test.swift:519:27:519:27 | SSA phi(a) | | test.swift:519:12:519:12 | a | test.swift:519:12:519:12 | SSA def(a) | | test.swift:519:16:519:16 | x | test.swift:519:8:519:12 | let ...? | | test.swift:519:16:519:16 | x | test.swift:524:19:524:19 | x | +| test.swift:519:19:519:23 | let ...? | test.swift:519:23:519:23 | b | | test.swift:519:23:519:23 | SSA def(b) | test.swift:521:19:521:19 | b | | test.swift:519:23:519:23 | b | test.swift:519:23:519:23 | SSA def(b) | | test.swift:519:27:519:27 | SSA phi(a) | test.swift:520:19:520:19 | a | @@ -600,6 +608,7 @@ | test.swift:526:21:526:21 | a | test.swift:526:21:526:21 | SSA def(a) | | test.swift:526:35:526:35 | SSA def(b) | test.swift:528:19:528:19 | b | | test.swift:526:35:526:35 | b | test.swift:526:35:526:35 | SSA def(b) | +| test.swift:533:8:533:17 | let ...? | test.swift:533:12:533:17 | (...) | | test.swift:533:13:533:13 | SSA def(x) | test.swift:534:19:534:19 | x | | test.swift:533:13:533:13 | x | test.swift:533:13:533:13 | SSA def(x) | | test.swift:533:16:533:16 | SSA def(y) | test.swift:535:19:535:19 | y | @@ -628,9 +637,11 @@ | test.swift:547:14:547:16 | call to C.init() | test.swift:547:9:547:9 | cy | | test.swift:548:5:548:5 | [post] cy | test.swift:552:20:552:20 | cy | | test.swift:548:5:548:5 | cy | test.swift:552:20:552:20 | cy | +| test.swift:550:11:550:15 | let ...? | test.swift:550:15:550:15 | z1 | | test.swift:550:15:550:15 | SSA def(z1) | test.swift:551:15:551:15 | z1 | | test.swift:550:15:550:15 | z1 | test.swift:550:15:550:15 | SSA def(z1) | | test.swift:550:20:550:23 | .x | test.swift:550:11:550:15 | let ...? | +| test.swift:552:11:552:15 | let ...? | test.swift:552:15:552:15 | z2 | | test.swift:552:15:552:15 | SSA def(z2) | test.swift:553:15:553:15 | z2 | | test.swift:552:15:552:15 | z2 | test.swift:552:15:552:15 | SSA def(z2) | | test.swift:552:20:552:23 | .x | test.swift:552:11:552:15 | let ...? | diff --git a/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected b/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected index 6fd724f31ad8..cb5fc364e9fc 100644 --- a/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected @@ -107,6 +107,8 @@ | conversions.swift:98:40:98:40 | parent | conversions.swift:98:25:98:69 | call to unsafeDowncast(_:to:) | | conversions.swift:99:12:99:12 | [post] v3 | conversions.swift:100:12:100:12 | v3 | | conversions.swift:99:12:99:12 | v3 | conversions.swift:100:12:100:12 | v3 | +| conversions.swift:107:24:107:24 | myCEnumConst | conversions.swift:107:12:107:36 | call to Self.init(_:) | +| conversions.swift:108:24:108:34 | call to sourceInt() | conversions.swift:108:12:108:35 | call to Self.init(_:) | | simple.swift:12:13:12:13 | 1 | simple.swift:12:13:12:24 | ... .+(_:_:) ... | | simple.swift:12:17:12:24 | call to source() | simple.swift:12:13:12:24 | ... .+(_:_:) ... | | simple.swift:13:13:13:20 | call to source() | simple.swift:13:13:13:24 | ... .+(_:_:) ... | diff --git a/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected b/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected index 25b8d79aa68e..427040adc40e 100644 --- a/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected @@ -47,6 +47,7 @@ edges | conversions.swift:98:25:98:69 | call to unsafeDowncast(_:to:) | conversions.swift:99:12:99:12 | v3 | | conversions.swift:98:25:98:69 | call to unsafeDowncast(_:to:) | conversions.swift:100:12:100:12 | v3 | | conversions.swift:98:40:98:40 | parent | conversions.swift:98:25:98:69 | call to unsafeDowncast(_:to:) | +| conversions.swift:108:24:108:34 | call to sourceInt() | conversions.swift:108:12:108:35 | call to Self.init(_:) | | file://:0:0:0:0 | self [first] | file://:0:0:0:0 | .first | | file://:0:0:0:0 | self [second] | file://:0:0:0:0 | .second | | file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [first] | @@ -206,6 +207,8 @@ nodes | conversions.swift:98:40:98:40 | parent | semmle.label | parent | | conversions.swift:99:12:99:12 | v3 | semmle.label | v3 | | conversions.swift:100:12:100:12 | v3 | semmle.label | v3 | +| conversions.swift:108:12:108:35 | call to Self.init(_:) | semmle.label | call to Self.init(_:) | +| conversions.swift:108:24:108:34 | call to sourceInt() | semmle.label | call to sourceInt() | | file://:0:0:0:0 | .first | semmle.label | .first | | file://:0:0:0:0 | .second | semmle.label | .second | | file://:0:0:0:0 | [post] self [first] | semmle.label | [post] self [first] | @@ -366,6 +369,7 @@ subpaths | conversions.swift:96:12:96:12 | parent | conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:96:12:96:12 | parent | result | | conversions.swift:99:12:99:12 | v3 | conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:99:12:99:12 | v3 | result | | conversions.swift:100:12:100:12 | v3 | conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:100:12:100:12 | v3 | result | +| conversions.swift:108:12:108:35 | call to Self.init(_:) | conversions.swift:108:24:108:34 | call to sourceInt() | conversions.swift:108:12:108:35 | call to Self.init(_:) | result | | simple.swift:12:13:12:24 | ... .+(_:_:) ... | simple.swift:12:17:12:24 | call to source() | simple.swift:12:13:12:24 | ... .+(_:_:) ... | result | | simple.swift:13:13:13:24 | ... .+(_:_:) ... | simple.swift:13:13:13:20 | call to source() | simple.swift:13:13:13:24 | ... .+(_:_:) ... | result | | simple.swift:14:13:14:24 | ... .-(_:_:) ... | simple.swift:14:17:14:24 | call to source() | simple.swift:14:13:14:24 | ... .-(_:_:) ... | result | From 0a2e4def8e925b5a3c62b429443124982a3c95eb Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 10 Aug 2023 19:53:24 +0100 Subject: [PATCH 07/20] Swift: Change note. --- swift/ql/lib/change-notes/2023-08-10-numeric-models.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 swift/ql/lib/change-notes/2023-08-10-numeric-models.md diff --git a/swift/ql/lib/change-notes/2023-08-10-numeric-models.md b/swift/ql/lib/change-notes/2023-08-10-numeric-models.md new file mode 100644 index 000000000000..85812d99c103 --- /dev/null +++ b/swift/ql/lib/change-notes/2023-08-10-numeric-models.md @@ -0,0 +1,5 @@ +--- +category: minorAnalysis +--- + +* Added taint models for `Numeric` conversions. From 9a4410d4b764e58e82ee048adc3f6ef0227d4b7f Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 16 Aug 2023 11:53:05 +0100 Subject: [PATCH 08/20] Swift: Additional test cases for array conversions. --- .../dataflow/taint/core/LocalTaint.expected | 195 +++++----- .../dataflow/taint/core/Taint.expected | 348 +++++++++--------- .../dataflow/taint/core/conversions.swift | 87 +++-- 3 files changed, 329 insertions(+), 301 deletions(-) diff --git a/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected b/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected index cb5fc364e9fc..5953d76c22d5 100644 --- a/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected @@ -17,98 +17,109 @@ | conversions.swift:19:33:19:33 | self | conversions.swift:19:33:19:33 | SSA def(self) | | conversions.swift:20:22:20:22 | SSA def(self) | conversions.swift:20:22:20:38 | self[return] | | conversions.swift:20:22:20:22 | self | conversions.swift:20:22:20:22 | SSA def(self) | -| conversions.swift:25:16:25:26 | call to sourceInt() | conversions.swift:25:12:25:27 | call to Self.init(_:) | -| conversions.swift:26:18:26:28 | call to sourceInt() | conversions.swift:26:12:26:29 | call to Self.init(_:) | -| conversions.swift:27:18:27:28 | call to sourceInt() | conversions.swift:27:12:27:29 | call to Float.init(_:) | -| conversions.swift:28:19:28:29 | call to sourceInt() | conversions.swift:28:12:28:30 | call to String.init(_:) | -| conversions.swift:29:12:29:30 | call to String.init(_:) | conversions.swift:29:12:29:32 | .utf8 | -| conversions.swift:29:19:29:29 | call to sourceInt() | conversions.swift:29:12:29:30 | call to String.init(_:) | -| conversions.swift:30:20:30:33 | call to sourceString() | conversions.swift:30:20:30:35 | .utf8 | -| conversions.swift:32:5:32:9 | let ...? | conversions.swift:32:9:32:9 | v | -| conversions.swift:32:9:32:9 | SSA def(v) | conversions.swift:33:13:33:13 | v | -| conversions.swift:32:9:32:9 | v | conversions.swift:32:9:32:9 | SSA def(v) | -| conversions.swift:32:13:32:23 | call to sourceInt() | conversions.swift:32:5:32:9 | let ...? | -| conversions.swift:36:6:36:6 | SSA def(v2) | conversions.swift:37:12:37:12 | v2 | -| conversions.swift:36:6:36:6 | v2 | conversions.swift:36:6:36:6 | SSA def(v2) | -| conversions.swift:36:6:36:10 | ... as ... | conversions.swift:36:6:36:6 | v2 | -| conversions.swift:36:18:36:41 | call to numericCast(_:) | conversions.swift:36:6:36:10 | ... as ... | -| conversions.swift:36:30:36:40 | call to sourceInt() | conversions.swift:36:18:36:41 | call to numericCast(_:) | -| conversions.swift:39:6:39:6 | SSA def(v4) | conversions.swift:40:12:40:12 | v4 | -| conversions.swift:39:6:39:6 | v4 | conversions.swift:39:6:39:6 | SSA def(v4) | -| conversions.swift:39:6:39:10 | ... as ... | conversions.swift:39:6:39:6 | v4 | -| conversions.swift:39:17:39:57 | call to unsafeBitCast(_:to:) | conversions.swift:39:6:39:10 | ... as ... | -| conversions.swift:39:31:39:41 | call to sourceInt() | conversions.swift:39:17:39:57 | call to unsafeBitCast(_:to:) | -| conversions.swift:42:6:42:6 | SSA def(v5) | conversions.swift:43:12:43:12 | v5 | -| conversions.swift:42:6:42:6 | v5 | conversions.swift:42:6:42:6 | SSA def(v5) | -| conversions.swift:42:11:42:47 | call to Self.init(truncatingIfNeeded:) | conversions.swift:42:6:42:6 | v5 | -| conversions.swift:42:36:42:46 | call to sourceInt() | conversions.swift:42:11:42:47 | call to Self.init(truncatingIfNeeded:) | -| conversions.swift:45:6:45:6 | SSA def(v6) | conversions.swift:46:12:46:12 | v6 | -| conversions.swift:45:6:45:6 | v6 | conversions.swift:45:6:45:6 | SSA def(v6) | -| conversions.swift:45:11:45:39 | call to UInt.init(bitPattern:) | conversions.swift:45:6:45:6 | v6 | -| conversions.swift:45:28:45:38 | call to sourceInt() | conversions.swift:45:11:45:39 | call to UInt.init(bitPattern:) | -| conversions.swift:48:12:48:36 | call to Self.init(exactly:) | conversions.swift:48:12:48:37 | ...! | -| conversions.swift:49:26:49:36 | call to sourceInt() | conversions.swift:49:12:49:37 | call to Self.init(clamping:) | -| conversions.swift:50:36:50:46 | call to sourceInt() | conversions.swift:50:12:50:47 | call to Self.init(truncatingIfNeeded:) | -| conversions.swift:51:12:51:41 | call to Self.init(_:radix:) | conversions.swift:51:12:51:42 | ...! | -| conversions.swift:51:16:51:29 | call to sourceString() | conversions.swift:51:12:51:41 | call to Self.init(_:radix:) | -| conversions.swift:53:30:53:40 | call to sourceInt() | conversions.swift:53:12:53:41 | call to Self.init(littleEndian:) | -| conversions.swift:54:27:54:37 | call to sourceInt() | conversions.swift:54:12:54:38 | call to Self.init(bigEndian:) | -| conversions.swift:55:12:55:22 | call to sourceInt() | conversions.swift:55:12:55:24 | .littleEndian | -| conversions.swift:56:12:56:22 | call to sourceInt() | conversions.swift:56:12:56:24 | .bigEndian | -| conversions.swift:61:18:61:30 | call to sourceFloat() | conversions.swift:61:12:61:31 | call to Float.init(_:) | -| conversions.swift:62:18:62:30 | call to sourceFloat() | conversions.swift:62:12:62:31 | call to UInt8.init(_:) | -| conversions.swift:63:19:63:31 | call to sourceFloat() | conversions.swift:63:12:63:32 | call to String.init(_:) | -| conversions.swift:64:12:64:32 | call to String.init(_:) | conversions.swift:64:12:64:34 | .utf8 | -| conversions.swift:64:19:64:31 | call to sourceFloat() | conversions.swift:64:12:64:32 | call to String.init(_:) | -| conversions.swift:66:18:66:30 | call to sourceFloat() | conversions.swift:66:12:66:31 | call to Float.init(_:) | -| conversions.swift:67:41:67:51 | call to sourceInt() | conversions.swift:67:12:67:70 | call to Float.init(sign:exponent:significand:) | -| conversions.swift:67:67:67:67 | 0.0 | conversions.swift:67:12:67:70 | call to Float.init(sign:exponent:significand:) | -| conversions.swift:68:41:68:41 | 0 | conversions.swift:68:12:68:70 | call to Float.init(sign:exponent:significand:) | -| conversions.swift:68:57:68:69 | call to sourceFloat() | conversions.swift:68:12:68:70 | call to Float.init(sign:exponent:significand:) | -| conversions.swift:69:54:69:54 | 0.0 | conversions.swift:69:12:69:57 | call to Float.init(signOf:magnitudeOf:) | -| conversions.swift:70:44:70:56 | call to sourceFloat() | conversions.swift:70:12:70:57 | call to Float.init(signOf:magnitudeOf:) | -| conversions.swift:72:12:72:24 | call to sourceFloat() | conversions.swift:72:12:72:26 | .exponent | -| conversions.swift:73:12:73:24 | call to sourceFloat() | conversions.swift:73:12:73:26 | .significand | -| conversions.swift:78:19:78:32 | call to sourceString() | conversions.swift:78:12:78:33 | call to String.init(_:) | -| conversions.swift:80:6:80:6 | SSA def(ms1) | conversions.swift:81:12:81:12 | ms1 | -| conversions.swift:80:6:80:6 | ms1 | conversions.swift:80:6:80:6 | SSA def(ms1) | -| conversions.swift:80:12:80:26 | call to MyString.init(_:) | conversions.swift:80:12:80:27 | ...! | -| conversions.swift:80:12:80:27 | ...! | conversions.swift:80:6:80:6 | ms1 | -| conversions.swift:80:21:80:21 | abc | conversions.swift:80:12:80:26 | call to MyString.init(_:) | -| conversions.swift:81:12:81:12 | [post] ms1 | conversions.swift:82:12:82:12 | ms1 | -| conversions.swift:81:12:81:12 | ms1 | conversions.swift:82:12:82:12 | ms1 | -| conversions.swift:82:12:82:12 | [post] ms1 | conversions.swift:83:12:83:12 | ms1 | -| conversions.swift:82:12:82:12 | ms1 | conversions.swift:83:12:83:12 | ms1 | -| conversions.swift:83:12:83:12 | [post] ms1 | conversions.swift:84:12:84:12 | ms1 | -| conversions.swift:83:12:83:12 | ms1 | conversions.swift:84:12:84:12 | ms1 | -| conversions.swift:86:6:86:6 | SSA def(ms2) | conversions.swift:87:12:87:12 | ms2 | -| conversions.swift:86:6:86:6 | ms2 | conversions.swift:86:6:86:6 | SSA def(ms2) | -| conversions.swift:86:12:86:35 | call to MyString.init(_:) | conversions.swift:86:12:86:36 | ...! | -| conversions.swift:86:12:86:36 | ...! | conversions.swift:86:6:86:6 | ms2 | -| conversions.swift:86:21:86:34 | call to sourceString() | conversions.swift:86:12:86:35 | call to MyString.init(_:) | -| conversions.swift:87:12:87:12 | [post] ms2 | conversions.swift:88:12:88:12 | ms2 | -| conversions.swift:87:12:87:12 | ms2 | conversions.swift:88:12:88:12 | ms2 | -| conversions.swift:88:12:88:12 | [post] ms2 | conversions.swift:89:12:89:12 | ms2 | -| conversions.swift:88:12:88:12 | ms2 | conversions.swift:89:12:89:12 | ms2 | -| conversions.swift:89:12:89:12 | [post] ms2 | conversions.swift:90:12:90:12 | ms2 | -| conversions.swift:89:12:89:12 | ms2 | conversions.swift:90:12:90:12 | ms2 | -| conversions.swift:94:6:94:6 | SSA def(parent) | conversions.swift:95:12:95:12 | parent | -| conversions.swift:94:6:94:6 | parent | conversions.swift:94:6:94:6 | SSA def(parent) | -| conversions.swift:94:6:94:15 | ... as ... | conversions.swift:94:6:94:6 | parent | -| conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:94:6:94:15 | ... as ... | -| conversions.swift:95:12:95:12 | [post] parent | conversions.swift:96:12:96:12 | parent | -| conversions.swift:95:12:95:12 | parent | conversions.swift:96:12:96:12 | parent | -| conversions.swift:96:12:96:12 | [post] parent | conversions.swift:98:40:98:40 | parent | -| conversions.swift:96:12:96:12 | parent | conversions.swift:98:40:98:40 | parent | -| conversions.swift:98:6:98:6 | SSA def(v3) | conversions.swift:99:12:99:12 | v3 | -| conversions.swift:98:6:98:6 | v3 | conversions.swift:98:6:98:6 | SSA def(v3) | -| conversions.swift:98:6:98:10 | ... as ... | conversions.swift:98:6:98:6 | v3 | -| conversions.swift:98:25:98:69 | call to unsafeDowncast(_:to:) | conversions.swift:98:6:98:10 | ... as ... | -| conversions.swift:98:40:98:40 | parent | conversions.swift:98:25:98:69 | call to unsafeDowncast(_:to:) | -| conversions.swift:99:12:99:12 | [post] v3 | conversions.swift:100:12:100:12 | v3 | -| conversions.swift:99:12:99:12 | v3 | conversions.swift:100:12:100:12 | v3 | -| conversions.swift:107:24:107:24 | myCEnumConst | conversions.swift:107:12:107:36 | call to Self.init(_:) | -| conversions.swift:108:24:108:34 | call to sourceInt() | conversions.swift:108:12:108:35 | call to Self.init(_:) | +| conversions.swift:27:16:27:26 | call to sourceInt() | conversions.swift:27:12:27:27 | call to Self.init(_:) | +| conversions.swift:28:18:28:28 | call to sourceInt() | conversions.swift:28:12:28:29 | call to Self.init(_:) | +| conversions.swift:29:18:29:28 | call to sourceInt() | conversions.swift:29:12:29:29 | call to Float.init(_:) | +| conversions.swift:30:19:30:29 | call to sourceInt() | conversions.swift:30:12:30:30 | call to String.init(_:) | +| conversions.swift:31:12:31:30 | call to String.init(_:) | conversions.swift:31:12:31:32 | .utf8 | +| conversions.swift:31:19:31:29 | call to sourceInt() | conversions.swift:31:12:31:30 | call to String.init(_:) | +| conversions.swift:33:6:33:6 | SSA def(arr) | conversions.swift:34:12:34:12 | arr | +| conversions.swift:33:6:33:6 | arr | conversions.swift:33:6:33:6 | SSA def(arr) | +| conversions.swift:33:12:33:30 | [...] | conversions.swift:33:6:33:6 | arr | +| conversions.swift:34:12:34:12 | arr | conversions.swift:35:12:35:12 | arr | +| conversions.swift:35:12:35:12 | [post] arr | conversions.swift:36:20:36:20 | arr | +| conversions.swift:35:12:35:12 | arr | conversions.swift:35:12:35:17 | ...[...] | +| conversions.swift:35:12:35:12 | arr | conversions.swift:36:20:36:20 | arr | +| conversions.swift:36:20:36:20 | arr | conversions.swift:37:20:37:20 | arr | +| conversions.swift:37:12:37:23 | call to Array.init(_:) | conversions.swift:37:12:37:26 | ...[...] | +| conversions.swift:38:20:38:33 | call to sourceString() | conversions.swift:38:20:38:35 | .utf8 | +| conversions.swift:39:12:39:39 | call to Array.init(_:) | conversions.swift:39:12:39:42 | ...[...] | +| conversions.swift:39:20:39:33 | call to sourceString() | conversions.swift:39:20:39:35 | .utf8 | +| conversions.swift:41:5:41:9 | let ...? | conversions.swift:41:9:41:9 | v | +| conversions.swift:41:9:41:9 | SSA def(v) | conversions.swift:42:13:42:13 | v | +| conversions.swift:41:9:41:9 | v | conversions.swift:41:9:41:9 | SSA def(v) | +| conversions.swift:41:13:41:23 | call to sourceInt() | conversions.swift:41:5:41:9 | let ...? | +| conversions.swift:45:6:45:6 | SSA def(v2) | conversions.swift:46:12:46:12 | v2 | +| conversions.swift:45:6:45:6 | v2 | conversions.swift:45:6:45:6 | SSA def(v2) | +| conversions.swift:45:6:45:10 | ... as ... | conversions.swift:45:6:45:6 | v2 | +| conversions.swift:45:18:45:41 | call to numericCast(_:) | conversions.swift:45:6:45:10 | ... as ... | +| conversions.swift:45:30:45:40 | call to sourceInt() | conversions.swift:45:18:45:41 | call to numericCast(_:) | +| conversions.swift:48:6:48:6 | SSA def(v4) | conversions.swift:49:12:49:12 | v4 | +| conversions.swift:48:6:48:6 | v4 | conversions.swift:48:6:48:6 | SSA def(v4) | +| conversions.swift:48:6:48:10 | ... as ... | conversions.swift:48:6:48:6 | v4 | +| conversions.swift:48:17:48:57 | call to unsafeBitCast(_:to:) | conversions.swift:48:6:48:10 | ... as ... | +| conversions.swift:48:31:48:41 | call to sourceInt() | conversions.swift:48:17:48:57 | call to unsafeBitCast(_:to:) | +| conversions.swift:51:6:51:6 | SSA def(v5) | conversions.swift:52:12:52:12 | v5 | +| conversions.swift:51:6:51:6 | v5 | conversions.swift:51:6:51:6 | SSA def(v5) | +| conversions.swift:51:11:51:47 | call to Self.init(truncatingIfNeeded:) | conversions.swift:51:6:51:6 | v5 | +| conversions.swift:51:36:51:46 | call to sourceInt() | conversions.swift:51:11:51:47 | call to Self.init(truncatingIfNeeded:) | +| conversions.swift:54:6:54:6 | SSA def(v6) | conversions.swift:55:12:55:12 | v6 | +| conversions.swift:54:6:54:6 | v6 | conversions.swift:54:6:54:6 | SSA def(v6) | +| conversions.swift:54:11:54:39 | call to UInt.init(bitPattern:) | conversions.swift:54:6:54:6 | v6 | +| conversions.swift:54:28:54:38 | call to sourceInt() | conversions.swift:54:11:54:39 | call to UInt.init(bitPattern:) | +| conversions.swift:57:12:57:36 | call to Self.init(exactly:) | conversions.swift:57:12:57:37 | ...! | +| conversions.swift:58:26:58:36 | call to sourceInt() | conversions.swift:58:12:58:37 | call to Self.init(clamping:) | +| conversions.swift:59:36:59:46 | call to sourceInt() | conversions.swift:59:12:59:47 | call to Self.init(truncatingIfNeeded:) | +| conversions.swift:60:12:60:41 | call to Self.init(_:radix:) | conversions.swift:60:12:60:42 | ...! | +| conversions.swift:60:16:60:29 | call to sourceString() | conversions.swift:60:12:60:41 | call to Self.init(_:radix:) | +| conversions.swift:62:30:62:40 | call to sourceInt() | conversions.swift:62:12:62:41 | call to Self.init(littleEndian:) | +| conversions.swift:63:27:63:37 | call to sourceInt() | conversions.swift:63:12:63:38 | call to Self.init(bigEndian:) | +| conversions.swift:64:12:64:22 | call to sourceInt() | conversions.swift:64:12:64:24 | .littleEndian | +| conversions.swift:65:12:65:22 | call to sourceInt() | conversions.swift:65:12:65:24 | .bigEndian | +| conversions.swift:70:18:70:30 | call to sourceFloat() | conversions.swift:70:12:70:31 | call to Float.init(_:) | +| conversions.swift:71:18:71:30 | call to sourceFloat() | conversions.swift:71:12:71:31 | call to UInt8.init(_:) | +| conversions.swift:72:19:72:31 | call to sourceFloat() | conversions.swift:72:12:72:32 | call to String.init(_:) | +| conversions.swift:73:12:73:32 | call to String.init(_:) | conversions.swift:73:12:73:34 | .utf8 | +| conversions.swift:73:19:73:31 | call to sourceFloat() | conversions.swift:73:12:73:32 | call to String.init(_:) | +| conversions.swift:75:18:75:30 | call to sourceFloat() | conversions.swift:75:12:75:31 | call to Float.init(_:) | +| conversions.swift:76:41:76:51 | call to sourceInt() | conversions.swift:76:12:76:70 | call to Float.init(sign:exponent:significand:) | +| conversions.swift:76:67:76:67 | 0.0 | conversions.swift:76:12:76:70 | call to Float.init(sign:exponent:significand:) | +| conversions.swift:77:41:77:41 | 0 | conversions.swift:77:12:77:70 | call to Float.init(sign:exponent:significand:) | +| conversions.swift:77:57:77:69 | call to sourceFloat() | conversions.swift:77:12:77:70 | call to Float.init(sign:exponent:significand:) | +| conversions.swift:78:54:78:54 | 0.0 | conversions.swift:78:12:78:57 | call to Float.init(signOf:magnitudeOf:) | +| conversions.swift:79:44:79:56 | call to sourceFloat() | conversions.swift:79:12:79:57 | call to Float.init(signOf:magnitudeOf:) | +| conversions.swift:81:12:81:24 | call to sourceFloat() | conversions.swift:81:12:81:26 | .exponent | +| conversions.swift:82:12:82:24 | call to sourceFloat() | conversions.swift:82:12:82:26 | .significand | +| conversions.swift:87:19:87:32 | call to sourceString() | conversions.swift:87:12:87:33 | call to String.init(_:) | +| conversions.swift:89:6:89:6 | SSA def(ms1) | conversions.swift:90:12:90:12 | ms1 | +| conversions.swift:89:6:89:6 | ms1 | conversions.swift:89:6:89:6 | SSA def(ms1) | +| conversions.swift:89:12:89:26 | call to MyString.init(_:) | conversions.swift:89:12:89:27 | ...! | +| conversions.swift:89:12:89:27 | ...! | conversions.swift:89:6:89:6 | ms1 | +| conversions.swift:89:21:89:21 | abc | conversions.swift:89:12:89:26 | call to MyString.init(_:) | +| conversions.swift:90:12:90:12 | [post] ms1 | conversions.swift:91:12:91:12 | ms1 | +| conversions.swift:90:12:90:12 | ms1 | conversions.swift:91:12:91:12 | ms1 | +| conversions.swift:91:12:91:12 | [post] ms1 | conversions.swift:92:12:92:12 | ms1 | +| conversions.swift:91:12:91:12 | ms1 | conversions.swift:92:12:92:12 | ms1 | +| conversions.swift:92:12:92:12 | [post] ms1 | conversions.swift:93:12:93:12 | ms1 | +| conversions.swift:92:12:92:12 | ms1 | conversions.swift:93:12:93:12 | ms1 | +| conversions.swift:95:6:95:6 | SSA def(ms2) | conversions.swift:96:12:96:12 | ms2 | +| conversions.swift:95:6:95:6 | ms2 | conversions.swift:95:6:95:6 | SSA def(ms2) | +| conversions.swift:95:12:95:35 | call to MyString.init(_:) | conversions.swift:95:12:95:36 | ...! | +| conversions.swift:95:12:95:36 | ...! | conversions.swift:95:6:95:6 | ms2 | +| conversions.swift:95:21:95:34 | call to sourceString() | conversions.swift:95:12:95:35 | call to MyString.init(_:) | +| conversions.swift:96:12:96:12 | [post] ms2 | conversions.swift:97:12:97:12 | ms2 | +| conversions.swift:96:12:96:12 | ms2 | conversions.swift:97:12:97:12 | ms2 | +| conversions.swift:97:12:97:12 | [post] ms2 | conversions.swift:98:12:98:12 | ms2 | +| conversions.swift:97:12:97:12 | ms2 | conversions.swift:98:12:98:12 | ms2 | +| conversions.swift:98:12:98:12 | [post] ms2 | conversions.swift:99:12:99:12 | ms2 | +| conversions.swift:98:12:98:12 | ms2 | conversions.swift:99:12:99:12 | ms2 | +| conversions.swift:103:6:103:6 | SSA def(parent) | conversions.swift:104:12:104:12 | parent | +| conversions.swift:103:6:103:6 | parent | conversions.swift:103:6:103:6 | SSA def(parent) | +| conversions.swift:103:6:103:15 | ... as ... | conversions.swift:103:6:103:6 | parent | +| conversions.swift:103:31:103:44 | call to sourceString() | conversions.swift:103:6:103:15 | ... as ... | +| conversions.swift:104:12:104:12 | [post] parent | conversions.swift:105:12:105:12 | parent | +| conversions.swift:104:12:104:12 | parent | conversions.swift:105:12:105:12 | parent | +| conversions.swift:105:12:105:12 | [post] parent | conversions.swift:107:40:107:40 | parent | +| conversions.swift:105:12:105:12 | parent | conversions.swift:107:40:107:40 | parent | +| conversions.swift:107:6:107:6 | SSA def(v3) | conversions.swift:108:12:108:12 | v3 | +| conversions.swift:107:6:107:6 | v3 | conversions.swift:107:6:107:6 | SSA def(v3) | +| conversions.swift:107:6:107:10 | ... as ... | conversions.swift:107:6:107:6 | v3 | +| conversions.swift:107:25:107:69 | call to unsafeDowncast(_:to:) | conversions.swift:107:6:107:10 | ... as ... | +| conversions.swift:107:40:107:40 | parent | conversions.swift:107:25:107:69 | call to unsafeDowncast(_:to:) | +| conversions.swift:108:12:108:12 | [post] v3 | conversions.swift:109:12:109:12 | v3 | +| conversions.swift:108:12:108:12 | v3 | conversions.swift:109:12:109:12 | v3 | +| conversions.swift:116:24:116:24 | myCEnumConst | conversions.swift:116:12:116:36 | call to Self.init(_:) | +| conversions.swift:117:24:117:34 | call to sourceInt() | conversions.swift:117:12:117:35 | call to Self.init(_:) | | simple.swift:12:13:12:13 | 1 | simple.swift:12:13:12:24 | ... .+(_:_:) ... | | simple.swift:12:17:12:24 | call to source() | simple.swift:12:13:12:24 | ... .+(_:_:) ... | | simple.swift:13:13:13:20 | call to source() | simple.swift:13:13:13:24 | ... .+(_:_:) ... | diff --git a/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected b/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected index 427040adc40e..4f10e907be3c 100644 --- a/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected @@ -1,53 +1,56 @@ edges -| conversions.swift:25:16:25:26 | call to sourceInt() | conversions.swift:25:12:25:27 | call to Self.init(_:) | -| conversions.swift:26:18:26:28 | call to sourceInt() | conversions.swift:26:12:26:29 | call to Self.init(_:) | -| conversions.swift:27:18:27:28 | call to sourceInt() | conversions.swift:27:12:27:29 | call to Float.init(_:) | -| conversions.swift:28:19:28:29 | call to sourceInt() | conversions.swift:28:12:28:30 | call to String.init(_:) | -| conversions.swift:29:12:29:30 | call to String.init(_:) | conversions.swift:29:12:29:32 | .utf8 | -| conversions.swift:29:19:29:29 | call to sourceInt() | conversions.swift:29:12:29:30 | call to String.init(_:) | -| conversions.swift:32:13:32:23 | call to sourceInt() | conversions.swift:33:13:33:13 | v | -| conversions.swift:36:18:36:41 | call to numericCast(_:) | conversions.swift:37:12:37:12 | v2 | -| conversions.swift:36:30:36:40 | call to sourceInt() | conversions.swift:36:18:36:41 | call to numericCast(_:) | -| conversions.swift:39:17:39:57 | call to unsafeBitCast(_:to:) | conversions.swift:40:12:40:12 | v4 | -| conversions.swift:39:31:39:41 | call to sourceInt() | conversions.swift:39:17:39:57 | call to unsafeBitCast(_:to:) | -| conversions.swift:42:11:42:47 | call to Self.init(truncatingIfNeeded:) | conversions.swift:43:12:43:12 | v5 | -| conversions.swift:42:36:42:46 | call to sourceInt() | conversions.swift:42:11:42:47 | call to Self.init(truncatingIfNeeded:) | -| conversions.swift:45:11:45:39 | call to UInt.init(bitPattern:) | conversions.swift:46:12:46:12 | v6 | -| conversions.swift:45:28:45:38 | call to sourceInt() | conversions.swift:45:11:45:39 | call to UInt.init(bitPattern:) | -| conversions.swift:48:12:48:36 | call to Self.init(exactly:) [some:0] | conversions.swift:48:12:48:37 | ...! | -| conversions.swift:48:25:48:35 | call to sourceInt() | conversions.swift:48:12:48:36 | call to Self.init(exactly:) [some:0] | -| conversions.swift:49:26:49:36 | call to sourceInt() | conversions.swift:49:12:49:37 | call to Self.init(clamping:) | -| conversions.swift:50:36:50:46 | call to sourceInt() | conversions.swift:50:12:50:47 | call to Self.init(truncatingIfNeeded:) | -| conversions.swift:51:12:51:41 | call to Self.init(_:radix:) | conversions.swift:51:12:51:42 | ...! | -| conversions.swift:51:16:51:29 | call to sourceString() | conversions.swift:51:12:51:41 | call to Self.init(_:radix:) | -| conversions.swift:53:30:53:40 | call to sourceInt() | conversions.swift:53:12:53:41 | call to Self.init(littleEndian:) | -| conversions.swift:54:27:54:37 | call to sourceInt() | conversions.swift:54:12:54:38 | call to Self.init(bigEndian:) | -| conversions.swift:55:12:55:22 | call to sourceInt() | conversions.swift:55:12:55:24 | .littleEndian | -| conversions.swift:56:12:56:22 | call to sourceInt() | conversions.swift:56:12:56:24 | .bigEndian | -| conversions.swift:61:18:61:30 | call to sourceFloat() | conversions.swift:61:12:61:31 | call to Float.init(_:) | -| conversions.swift:62:18:62:30 | call to sourceFloat() | conversions.swift:62:12:62:31 | call to UInt8.init(_:) | -| conversions.swift:63:19:63:31 | call to sourceFloat() | conversions.swift:63:12:63:32 | call to String.init(_:) | -| conversions.swift:64:12:64:32 | call to String.init(_:) | conversions.swift:64:12:64:34 | .utf8 | -| conversions.swift:64:19:64:31 | call to sourceFloat() | conversions.swift:64:12:64:32 | call to String.init(_:) | -| conversions.swift:66:18:66:30 | call to sourceFloat() | conversions.swift:66:12:66:31 | call to Float.init(_:) | -| conversions.swift:67:41:67:51 | call to sourceInt() | conversions.swift:67:12:67:70 | call to Float.init(sign:exponent:significand:) | -| conversions.swift:68:57:68:69 | call to sourceFloat() | conversions.swift:68:12:68:70 | call to Float.init(sign:exponent:significand:) | -| conversions.swift:70:44:70:56 | call to sourceFloat() | conversions.swift:70:12:70:57 | call to Float.init(signOf:magnitudeOf:) | -| conversions.swift:72:12:72:24 | call to sourceFloat() | conversions.swift:72:12:72:26 | .exponent | -| conversions.swift:73:12:73:24 | call to sourceFloat() | conversions.swift:73:12:73:26 | .significand | -| conversions.swift:78:19:78:32 | call to sourceString() | conversions.swift:78:12:78:33 | call to String.init(_:) | -| conversions.swift:86:12:86:35 | call to MyString.init(_:) | conversions.swift:86:12:86:35 | call to MyString.init(_:) [some:0] | -| conversions.swift:86:12:86:35 | call to MyString.init(_:) | conversions.swift:87:12:87:12 | ms2 | -| conversions.swift:86:12:86:35 | call to MyString.init(_:) [some:0] | conversions.swift:86:12:86:36 | ...! | -| conversions.swift:86:12:86:36 | ...! | conversions.swift:87:12:87:12 | ms2 | -| conversions.swift:86:21:86:34 | call to sourceString() | conversions.swift:86:12:86:35 | call to MyString.init(_:) | -| conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:95:12:95:12 | parent | -| conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:96:12:96:12 | parent | -| conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:98:40:98:40 | parent | -| conversions.swift:98:25:98:69 | call to unsafeDowncast(_:to:) | conversions.swift:99:12:99:12 | v3 | -| conversions.swift:98:25:98:69 | call to unsafeDowncast(_:to:) | conversions.swift:100:12:100:12 | v3 | -| conversions.swift:98:40:98:40 | parent | conversions.swift:98:25:98:69 | call to unsafeDowncast(_:to:) | -| conversions.swift:108:24:108:34 | call to sourceInt() | conversions.swift:108:12:108:35 | call to Self.init(_:) | +| conversions.swift:27:16:27:26 | call to sourceInt() | conversions.swift:27:12:27:27 | call to Self.init(_:) | +| conversions.swift:28:18:28:28 | call to sourceInt() | conversions.swift:28:12:28:29 | call to Self.init(_:) | +| conversions.swift:29:18:29:28 | call to sourceInt() | conversions.swift:29:12:29:29 | call to Float.init(_:) | +| conversions.swift:30:19:30:29 | call to sourceInt() | conversions.swift:30:12:30:30 | call to String.init(_:) | +| conversions.swift:31:12:31:30 | call to String.init(_:) | conversions.swift:31:12:31:32 | .utf8 | +| conversions.swift:31:19:31:29 | call to sourceInt() | conversions.swift:31:12:31:30 | call to String.init(_:) | +| conversions.swift:33:12:33:30 | [...] [Array element] | conversions.swift:35:12:35:12 | arr [Array element] | +| conversions.swift:33:19:33:29 | call to sourceInt() | conversions.swift:33:12:33:30 | [...] [Array element] | +| conversions.swift:35:12:35:12 | arr [Array element] | conversions.swift:35:12:35:17 | ...[...] | +| conversions.swift:41:13:41:23 | call to sourceInt() | conversions.swift:42:13:42:13 | v | +| conversions.swift:45:18:45:41 | call to numericCast(_:) | conversions.swift:46:12:46:12 | v2 | +| conversions.swift:45:30:45:40 | call to sourceInt() | conversions.swift:45:18:45:41 | call to numericCast(_:) | +| conversions.swift:48:17:48:57 | call to unsafeBitCast(_:to:) | conversions.swift:49:12:49:12 | v4 | +| conversions.swift:48:31:48:41 | call to sourceInt() | conversions.swift:48:17:48:57 | call to unsafeBitCast(_:to:) | +| conversions.swift:51:11:51:47 | call to Self.init(truncatingIfNeeded:) | conversions.swift:52:12:52:12 | v5 | +| conversions.swift:51:36:51:46 | call to sourceInt() | conversions.swift:51:11:51:47 | call to Self.init(truncatingIfNeeded:) | +| conversions.swift:54:11:54:39 | call to UInt.init(bitPattern:) | conversions.swift:55:12:55:12 | v6 | +| conversions.swift:54:28:54:38 | call to sourceInt() | conversions.swift:54:11:54:39 | call to UInt.init(bitPattern:) | +| conversions.swift:57:12:57:36 | call to Self.init(exactly:) [some:0] | conversions.swift:57:12:57:37 | ...! | +| conversions.swift:57:25:57:35 | call to sourceInt() | conversions.swift:57:12:57:36 | call to Self.init(exactly:) [some:0] | +| conversions.swift:58:26:58:36 | call to sourceInt() | conversions.swift:58:12:58:37 | call to Self.init(clamping:) | +| conversions.swift:59:36:59:46 | call to sourceInt() | conversions.swift:59:12:59:47 | call to Self.init(truncatingIfNeeded:) | +| conversions.swift:60:12:60:41 | call to Self.init(_:radix:) | conversions.swift:60:12:60:42 | ...! | +| conversions.swift:60:16:60:29 | call to sourceString() | conversions.swift:60:12:60:41 | call to Self.init(_:radix:) | +| conversions.swift:62:30:62:40 | call to sourceInt() | conversions.swift:62:12:62:41 | call to Self.init(littleEndian:) | +| conversions.swift:63:27:63:37 | call to sourceInt() | conversions.swift:63:12:63:38 | call to Self.init(bigEndian:) | +| conversions.swift:64:12:64:22 | call to sourceInt() | conversions.swift:64:12:64:24 | .littleEndian | +| conversions.swift:65:12:65:22 | call to sourceInt() | conversions.swift:65:12:65:24 | .bigEndian | +| conversions.swift:70:18:70:30 | call to sourceFloat() | conversions.swift:70:12:70:31 | call to Float.init(_:) | +| conversions.swift:71:18:71:30 | call to sourceFloat() | conversions.swift:71:12:71:31 | call to UInt8.init(_:) | +| conversions.swift:72:19:72:31 | call to sourceFloat() | conversions.swift:72:12:72:32 | call to String.init(_:) | +| conversions.swift:73:12:73:32 | call to String.init(_:) | conversions.swift:73:12:73:34 | .utf8 | +| conversions.swift:73:19:73:31 | call to sourceFloat() | conversions.swift:73:12:73:32 | call to String.init(_:) | +| conversions.swift:75:18:75:30 | call to sourceFloat() | conversions.swift:75:12:75:31 | call to Float.init(_:) | +| conversions.swift:76:41:76:51 | call to sourceInt() | conversions.swift:76:12:76:70 | call to Float.init(sign:exponent:significand:) | +| conversions.swift:77:57:77:69 | call to sourceFloat() | conversions.swift:77:12:77:70 | call to Float.init(sign:exponent:significand:) | +| conversions.swift:79:44:79:56 | call to sourceFloat() | conversions.swift:79:12:79:57 | call to Float.init(signOf:magnitudeOf:) | +| conversions.swift:81:12:81:24 | call to sourceFloat() | conversions.swift:81:12:81:26 | .exponent | +| conversions.swift:82:12:82:24 | call to sourceFloat() | conversions.swift:82:12:82:26 | .significand | +| conversions.swift:87:19:87:32 | call to sourceString() | conversions.swift:87:12:87:33 | call to String.init(_:) | +| conversions.swift:95:12:95:35 | call to MyString.init(_:) | conversions.swift:95:12:95:35 | call to MyString.init(_:) [some:0] | +| conversions.swift:95:12:95:35 | call to MyString.init(_:) | conversions.swift:96:12:96:12 | ms2 | +| conversions.swift:95:12:95:35 | call to MyString.init(_:) [some:0] | conversions.swift:95:12:95:36 | ...! | +| conversions.swift:95:12:95:36 | ...! | conversions.swift:96:12:96:12 | ms2 | +| conversions.swift:95:21:95:34 | call to sourceString() | conversions.swift:95:12:95:35 | call to MyString.init(_:) | +| conversions.swift:103:31:103:44 | call to sourceString() | conversions.swift:104:12:104:12 | parent | +| conversions.swift:103:31:103:44 | call to sourceString() | conversions.swift:105:12:105:12 | parent | +| conversions.swift:103:31:103:44 | call to sourceString() | conversions.swift:107:40:107:40 | parent | +| conversions.swift:107:25:107:69 | call to unsafeDowncast(_:to:) | conversions.swift:108:12:108:12 | v3 | +| conversions.swift:107:25:107:69 | call to unsafeDowncast(_:to:) | conversions.swift:109:12:109:12 | v3 | +| conversions.swift:107:40:107:40 | parent | conversions.swift:107:25:107:69 | call to unsafeDowncast(_:to:) | +| conversions.swift:117:24:117:34 | call to sourceInt() | conversions.swift:117:12:117:35 | call to Self.init(_:) | | file://:0:0:0:0 | self [first] | file://:0:0:0:0 | .first | | file://:0:0:0:0 | self [second] | file://:0:0:0:0 | .second | | file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [first] | @@ -126,89 +129,93 @@ edges | try.swift:18:18:18:25 | call to source() | try.swift:18:18:18:25 | call to source() [some:0] | | try.swift:18:18:18:25 | call to source() [some:0] | try.swift:18:13:18:25 | try? ... [some:0] | nodes -| conversions.swift:24:12:24:22 | call to sourceInt() | semmle.label | call to sourceInt() | -| conversions.swift:25:12:25:27 | call to Self.init(_:) | semmle.label | call to Self.init(_:) | -| conversions.swift:25:16:25:26 | call to sourceInt() | semmle.label | call to sourceInt() | -| conversions.swift:26:12:26:29 | call to Self.init(_:) | semmle.label | call to Self.init(_:) | -| conversions.swift:26:18:26:28 | call to sourceInt() | semmle.label | call to sourceInt() | -| conversions.swift:27:12:27:29 | call to Float.init(_:) | semmle.label | call to Float.init(_:) | -| conversions.swift:27:18:27:28 | call to sourceInt() | semmle.label | call to sourceInt() | -| conversions.swift:28:12:28:30 | call to String.init(_:) | semmle.label | call to String.init(_:) | -| conversions.swift:28:19:28:29 | call to sourceInt() | semmle.label | call to sourceInt() | -| conversions.swift:29:12:29:30 | call to String.init(_:) | semmle.label | call to String.init(_:) | -| conversions.swift:29:12:29:32 | .utf8 | semmle.label | .utf8 | -| conversions.swift:29:19:29:29 | call to sourceInt() | semmle.label | call to sourceInt() | -| conversions.swift:32:13:32:23 | call to sourceInt() | semmle.label | call to sourceInt() | -| conversions.swift:33:13:33:13 | v | semmle.label | v | -| conversions.swift:36:18:36:41 | call to numericCast(_:) | semmle.label | call to numericCast(_:) | -| conversions.swift:36:30:36:40 | call to sourceInt() | semmle.label | call to sourceInt() | -| conversions.swift:37:12:37:12 | v2 | semmle.label | v2 | -| conversions.swift:39:17:39:57 | call to unsafeBitCast(_:to:) | semmle.label | call to unsafeBitCast(_:to:) | -| conversions.swift:39:31:39:41 | call to sourceInt() | semmle.label | call to sourceInt() | -| conversions.swift:40:12:40:12 | v4 | semmle.label | v4 | -| conversions.swift:42:11:42:47 | call to Self.init(truncatingIfNeeded:) | semmle.label | call to Self.init(truncatingIfNeeded:) | -| conversions.swift:42:36:42:46 | call to sourceInt() | semmle.label | call to sourceInt() | -| conversions.swift:43:12:43:12 | v5 | semmle.label | v5 | -| conversions.swift:45:11:45:39 | call to UInt.init(bitPattern:) | semmle.label | call to UInt.init(bitPattern:) | -| conversions.swift:45:28:45:38 | call to sourceInt() | semmle.label | call to sourceInt() | -| conversions.swift:46:12:46:12 | v6 | semmle.label | v6 | -| conversions.swift:48:12:48:36 | call to Self.init(exactly:) [some:0] | semmle.label | call to Self.init(exactly:) [some:0] | -| conversions.swift:48:12:48:37 | ...! | semmle.label | ...! | -| conversions.swift:48:25:48:35 | call to sourceInt() | semmle.label | call to sourceInt() | -| conversions.swift:49:12:49:37 | call to Self.init(clamping:) | semmle.label | call to Self.init(clamping:) | -| conversions.swift:49:26:49:36 | call to sourceInt() | semmle.label | call to sourceInt() | -| conversions.swift:50:12:50:47 | call to Self.init(truncatingIfNeeded:) | semmle.label | call to Self.init(truncatingIfNeeded:) | -| conversions.swift:50:36:50:46 | call to sourceInt() | semmle.label | call to sourceInt() | -| conversions.swift:51:12:51:41 | call to Self.init(_:radix:) | semmle.label | call to Self.init(_:radix:) | -| conversions.swift:51:12:51:42 | ...! | semmle.label | ...! | -| conversions.swift:51:16:51:29 | call to sourceString() | semmle.label | call to sourceString() | -| conversions.swift:53:12:53:41 | call to Self.init(littleEndian:) | semmle.label | call to Self.init(littleEndian:) | -| conversions.swift:53:30:53:40 | call to sourceInt() | semmle.label | call to sourceInt() | -| conversions.swift:54:12:54:38 | call to Self.init(bigEndian:) | semmle.label | call to Self.init(bigEndian:) | -| conversions.swift:54:27:54:37 | call to sourceInt() | semmle.label | call to sourceInt() | -| conversions.swift:55:12:55:22 | call to sourceInt() | semmle.label | call to sourceInt() | -| conversions.swift:55:12:55:24 | .littleEndian | semmle.label | .littleEndian | -| conversions.swift:56:12:56:22 | call to sourceInt() | semmle.label | call to sourceInt() | -| conversions.swift:56:12:56:24 | .bigEndian | semmle.label | .bigEndian | -| conversions.swift:60:12:60:24 | call to sourceFloat() | semmle.label | call to sourceFloat() | -| conversions.swift:61:12:61:31 | call to Float.init(_:) | semmle.label | call to Float.init(_:) | -| conversions.swift:61:18:61:30 | call to sourceFloat() | semmle.label | call to sourceFloat() | -| conversions.swift:62:12:62:31 | call to UInt8.init(_:) | semmle.label | call to UInt8.init(_:) | -| conversions.swift:62:18:62:30 | call to sourceFloat() | semmle.label | call to sourceFloat() | -| conversions.swift:63:12:63:32 | call to String.init(_:) | semmle.label | call to String.init(_:) | -| conversions.swift:63:19:63:31 | call to sourceFloat() | semmle.label | call to sourceFloat() | -| conversions.swift:64:12:64:32 | call to String.init(_:) | semmle.label | call to String.init(_:) | -| conversions.swift:64:12:64:34 | .utf8 | semmle.label | .utf8 | -| conversions.swift:64:19:64:31 | call to sourceFloat() | semmle.label | call to sourceFloat() | -| conversions.swift:66:12:66:31 | call to Float.init(_:) | semmle.label | call to Float.init(_:) | -| conversions.swift:66:18:66:30 | call to sourceFloat() | semmle.label | call to sourceFloat() | -| conversions.swift:67:12:67:70 | call to Float.init(sign:exponent:significand:) | semmle.label | call to Float.init(sign:exponent:significand:) | -| conversions.swift:67:41:67:51 | call to sourceInt() | semmle.label | call to sourceInt() | -| conversions.swift:68:12:68:70 | call to Float.init(sign:exponent:significand:) | semmle.label | call to Float.init(sign:exponent:significand:) | -| conversions.swift:68:57:68:69 | call to sourceFloat() | semmle.label | call to sourceFloat() | -| conversions.swift:70:12:70:57 | call to Float.init(signOf:magnitudeOf:) | semmle.label | call to Float.init(signOf:magnitudeOf:) | -| conversions.swift:70:44:70:56 | call to sourceFloat() | semmle.label | call to sourceFloat() | -| conversions.swift:72:12:72:24 | call to sourceFloat() | semmle.label | call to sourceFloat() | -| conversions.swift:72:12:72:26 | .exponent | semmle.label | .exponent | -| conversions.swift:73:12:73:24 | call to sourceFloat() | semmle.label | call to sourceFloat() | -| conversions.swift:73:12:73:26 | .significand | semmle.label | .significand | -| conversions.swift:77:12:77:25 | call to sourceString() | semmle.label | call to sourceString() | -| conversions.swift:78:12:78:33 | call to String.init(_:) | semmle.label | call to String.init(_:) | -| conversions.swift:78:19:78:32 | call to sourceString() | semmle.label | call to sourceString() | -| conversions.swift:86:12:86:35 | call to MyString.init(_:) | semmle.label | call to MyString.init(_:) | -| conversions.swift:86:12:86:35 | call to MyString.init(_:) [some:0] | semmle.label | call to MyString.init(_:) [some:0] | -| conversions.swift:86:12:86:36 | ...! | semmle.label | ...! | -| conversions.swift:86:21:86:34 | call to sourceString() | semmle.label | call to sourceString() | -| conversions.swift:87:12:87:12 | ms2 | semmle.label | ms2 | -| conversions.swift:94:31:94:44 | call to sourceString() | semmle.label | call to sourceString() | -| conversions.swift:95:12:95:12 | parent | semmle.label | parent | -| conversions.swift:96:12:96:12 | parent | semmle.label | parent | -| conversions.swift:98:25:98:69 | call to unsafeDowncast(_:to:) | semmle.label | call to unsafeDowncast(_:to:) | -| conversions.swift:98:40:98:40 | parent | semmle.label | parent | -| conversions.swift:99:12:99:12 | v3 | semmle.label | v3 | -| conversions.swift:100:12:100:12 | v3 | semmle.label | v3 | -| conversions.swift:108:12:108:35 | call to Self.init(_:) | semmle.label | call to Self.init(_:) | -| conversions.swift:108:24:108:34 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:26:12:26:22 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:27:12:27:27 | call to Self.init(_:) | semmle.label | call to Self.init(_:) | +| conversions.swift:27:16:27:26 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:28:12:28:29 | call to Self.init(_:) | semmle.label | call to Self.init(_:) | +| conversions.swift:28:18:28:28 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:29:12:29:29 | call to Float.init(_:) | semmle.label | call to Float.init(_:) | +| conversions.swift:29:18:29:28 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:30:12:30:30 | call to String.init(_:) | semmle.label | call to String.init(_:) | +| conversions.swift:30:19:30:29 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:31:12:31:30 | call to String.init(_:) | semmle.label | call to String.init(_:) | +| conversions.swift:31:12:31:32 | .utf8 | semmle.label | .utf8 | +| conversions.swift:31:19:31:29 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:33:12:33:30 | [...] [Array element] | semmle.label | [...] [Array element] | +| conversions.swift:33:19:33:29 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:35:12:35:12 | arr [Array element] | semmle.label | arr [Array element] | +| conversions.swift:35:12:35:17 | ...[...] | semmle.label | ...[...] | +| conversions.swift:41:13:41:23 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:42:13:42:13 | v | semmle.label | v | +| conversions.swift:45:18:45:41 | call to numericCast(_:) | semmle.label | call to numericCast(_:) | +| conversions.swift:45:30:45:40 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:46:12:46:12 | v2 | semmle.label | v2 | +| conversions.swift:48:17:48:57 | call to unsafeBitCast(_:to:) | semmle.label | call to unsafeBitCast(_:to:) | +| conversions.swift:48:31:48:41 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:49:12:49:12 | v4 | semmle.label | v4 | +| conversions.swift:51:11:51:47 | call to Self.init(truncatingIfNeeded:) | semmle.label | call to Self.init(truncatingIfNeeded:) | +| conversions.swift:51:36:51:46 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:52:12:52:12 | v5 | semmle.label | v5 | +| conversions.swift:54:11:54:39 | call to UInt.init(bitPattern:) | semmle.label | call to UInt.init(bitPattern:) | +| conversions.swift:54:28:54:38 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:55:12:55:12 | v6 | semmle.label | v6 | +| conversions.swift:57:12:57:36 | call to Self.init(exactly:) [some:0] | semmle.label | call to Self.init(exactly:) [some:0] | +| conversions.swift:57:12:57:37 | ...! | semmle.label | ...! | +| conversions.swift:57:25:57:35 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:58:12:58:37 | call to Self.init(clamping:) | semmle.label | call to Self.init(clamping:) | +| conversions.swift:58:26:58:36 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:59:12:59:47 | call to Self.init(truncatingIfNeeded:) | semmle.label | call to Self.init(truncatingIfNeeded:) | +| conversions.swift:59:36:59:46 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:60:12:60:41 | call to Self.init(_:radix:) | semmle.label | call to Self.init(_:radix:) | +| conversions.swift:60:12:60:42 | ...! | semmle.label | ...! | +| conversions.swift:60:16:60:29 | call to sourceString() | semmle.label | call to sourceString() | +| conversions.swift:62:12:62:41 | call to Self.init(littleEndian:) | semmle.label | call to Self.init(littleEndian:) | +| conversions.swift:62:30:62:40 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:63:12:63:38 | call to Self.init(bigEndian:) | semmle.label | call to Self.init(bigEndian:) | +| conversions.swift:63:27:63:37 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:64:12:64:22 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:64:12:64:24 | .littleEndian | semmle.label | .littleEndian | +| conversions.swift:65:12:65:22 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:65:12:65:24 | .bigEndian | semmle.label | .bigEndian | +| conversions.swift:69:12:69:24 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:70:12:70:31 | call to Float.init(_:) | semmle.label | call to Float.init(_:) | +| conversions.swift:70:18:70:30 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:71:12:71:31 | call to UInt8.init(_:) | semmle.label | call to UInt8.init(_:) | +| conversions.swift:71:18:71:30 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:72:12:72:32 | call to String.init(_:) | semmle.label | call to String.init(_:) | +| conversions.swift:72:19:72:31 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:73:12:73:32 | call to String.init(_:) | semmle.label | call to String.init(_:) | +| conversions.swift:73:12:73:34 | .utf8 | semmle.label | .utf8 | +| conversions.swift:73:19:73:31 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:75:12:75:31 | call to Float.init(_:) | semmle.label | call to Float.init(_:) | +| conversions.swift:75:18:75:30 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:76:12:76:70 | call to Float.init(sign:exponent:significand:) | semmle.label | call to Float.init(sign:exponent:significand:) | +| conversions.swift:76:41:76:51 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:77:12:77:70 | call to Float.init(sign:exponent:significand:) | semmle.label | call to Float.init(sign:exponent:significand:) | +| conversions.swift:77:57:77:69 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:79:12:79:57 | call to Float.init(signOf:magnitudeOf:) | semmle.label | call to Float.init(signOf:magnitudeOf:) | +| conversions.swift:79:44:79:56 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:81:12:81:24 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:81:12:81:26 | .exponent | semmle.label | .exponent | +| conversions.swift:82:12:82:24 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:82:12:82:26 | .significand | semmle.label | .significand | +| conversions.swift:86:12:86:25 | call to sourceString() | semmle.label | call to sourceString() | +| conversions.swift:87:12:87:33 | call to String.init(_:) | semmle.label | call to String.init(_:) | +| conversions.swift:87:19:87:32 | call to sourceString() | semmle.label | call to sourceString() | +| conversions.swift:95:12:95:35 | call to MyString.init(_:) | semmle.label | call to MyString.init(_:) | +| conversions.swift:95:12:95:35 | call to MyString.init(_:) [some:0] | semmle.label | call to MyString.init(_:) [some:0] | +| conversions.swift:95:12:95:36 | ...! | semmle.label | ...! | +| conversions.swift:95:21:95:34 | call to sourceString() | semmle.label | call to sourceString() | +| conversions.swift:96:12:96:12 | ms2 | semmle.label | ms2 | +| conversions.swift:103:31:103:44 | call to sourceString() | semmle.label | call to sourceString() | +| conversions.swift:104:12:104:12 | parent | semmle.label | parent | +| conversions.swift:105:12:105:12 | parent | semmle.label | parent | +| conversions.swift:107:25:107:69 | call to unsafeDowncast(_:to:) | semmle.label | call to unsafeDowncast(_:to:) | +| conversions.swift:107:40:107:40 | parent | semmle.label | parent | +| conversions.swift:108:12:108:12 | v3 | semmle.label | v3 | +| conversions.swift:109:12:109:12 | v3 | semmle.label | v3 | +| conversions.swift:117:12:117:35 | call to Self.init(_:) | semmle.label | call to Self.init(_:) | +| conversions.swift:117:24:117:34 | call to sourceInt() | semmle.label | call to sourceInt() | | file://:0:0:0:0 | .first | semmle.label | .first | | file://:0:0:0:0 | .second | semmle.label | .second | | file://:0:0:0:0 | [post] self [first] | semmle.label | [post] self [first] | @@ -332,44 +339,45 @@ subpaths | stringinterpolation.swift:28:14:28:21 | call to source() | stringinterpolation.swift:7:6:7:6 | value | file://:0:0:0:0 | [post] self [second] | stringinterpolation.swift:28:2:28:2 | [post] p2 [second] | | stringinterpolation.swift:31:21:31:21 | p2 [second] | stringinterpolation.swift:7:6:7:6 | self [second] | file://:0:0:0:0 | .second | stringinterpolation.swift:31:21:31:24 | .second | #select -| conversions.swift:24:12:24:22 | call to sourceInt() | conversions.swift:24:12:24:22 | call to sourceInt() | conversions.swift:24:12:24:22 | call to sourceInt() | result | -| conversions.swift:25:12:25:27 | call to Self.init(_:) | conversions.swift:25:16:25:26 | call to sourceInt() | conversions.swift:25:12:25:27 | call to Self.init(_:) | result | -| conversions.swift:26:12:26:29 | call to Self.init(_:) | conversions.swift:26:18:26:28 | call to sourceInt() | conversions.swift:26:12:26:29 | call to Self.init(_:) | result | -| conversions.swift:27:12:27:29 | call to Float.init(_:) | conversions.swift:27:18:27:28 | call to sourceInt() | conversions.swift:27:12:27:29 | call to Float.init(_:) | result | -| conversions.swift:28:12:28:30 | call to String.init(_:) | conversions.swift:28:19:28:29 | call to sourceInt() | conversions.swift:28:12:28:30 | call to String.init(_:) | result | -| conversions.swift:29:12:29:32 | .utf8 | conversions.swift:29:19:29:29 | call to sourceInt() | conversions.swift:29:12:29:32 | .utf8 | result | -| conversions.swift:33:13:33:13 | v | conversions.swift:32:13:32:23 | call to sourceInt() | conversions.swift:33:13:33:13 | v | result | -| conversions.swift:37:12:37:12 | v2 | conversions.swift:36:30:36:40 | call to sourceInt() | conversions.swift:37:12:37:12 | v2 | result | -| conversions.swift:40:12:40:12 | v4 | conversions.swift:39:31:39:41 | call to sourceInt() | conversions.swift:40:12:40:12 | v4 | result | -| conversions.swift:43:12:43:12 | v5 | conversions.swift:42:36:42:46 | call to sourceInt() | conversions.swift:43:12:43:12 | v5 | result | -| conversions.swift:46:12:46:12 | v6 | conversions.swift:45:28:45:38 | call to sourceInt() | conversions.swift:46:12:46:12 | v6 | result | -| conversions.swift:48:12:48:37 | ...! | conversions.swift:48:25:48:35 | call to sourceInt() | conversions.swift:48:12:48:37 | ...! | result | -| conversions.swift:49:12:49:37 | call to Self.init(clamping:) | conversions.swift:49:26:49:36 | call to sourceInt() | conversions.swift:49:12:49:37 | call to Self.init(clamping:) | result | -| conversions.swift:50:12:50:47 | call to Self.init(truncatingIfNeeded:) | conversions.swift:50:36:50:46 | call to sourceInt() | conversions.swift:50:12:50:47 | call to Self.init(truncatingIfNeeded:) | result | -| conversions.swift:51:12:51:42 | ...! | conversions.swift:51:16:51:29 | call to sourceString() | conversions.swift:51:12:51:42 | ...! | result | -| conversions.swift:53:12:53:41 | call to Self.init(littleEndian:) | conversions.swift:53:30:53:40 | call to sourceInt() | conversions.swift:53:12:53:41 | call to Self.init(littleEndian:) | result | -| conversions.swift:54:12:54:38 | call to Self.init(bigEndian:) | conversions.swift:54:27:54:37 | call to sourceInt() | conversions.swift:54:12:54:38 | call to Self.init(bigEndian:) | result | -| conversions.swift:55:12:55:24 | .littleEndian | conversions.swift:55:12:55:22 | call to sourceInt() | conversions.swift:55:12:55:24 | .littleEndian | result | -| conversions.swift:56:12:56:24 | .bigEndian | conversions.swift:56:12:56:22 | call to sourceInt() | conversions.swift:56:12:56:24 | .bigEndian | result | -| conversions.swift:60:12:60:24 | call to sourceFloat() | conversions.swift:60:12:60:24 | call to sourceFloat() | conversions.swift:60:12:60:24 | call to sourceFloat() | result | -| conversions.swift:61:12:61:31 | call to Float.init(_:) | conversions.swift:61:18:61:30 | call to sourceFloat() | conversions.swift:61:12:61:31 | call to Float.init(_:) | result | -| conversions.swift:62:12:62:31 | call to UInt8.init(_:) | conversions.swift:62:18:62:30 | call to sourceFloat() | conversions.swift:62:12:62:31 | call to UInt8.init(_:) | result | -| conversions.swift:63:12:63:32 | call to String.init(_:) | conversions.swift:63:19:63:31 | call to sourceFloat() | conversions.swift:63:12:63:32 | call to String.init(_:) | result | -| conversions.swift:64:12:64:34 | .utf8 | conversions.swift:64:19:64:31 | call to sourceFloat() | conversions.swift:64:12:64:34 | .utf8 | result | -| conversions.swift:66:12:66:31 | call to Float.init(_:) | conversions.swift:66:18:66:30 | call to sourceFloat() | conversions.swift:66:12:66:31 | call to Float.init(_:) | result | -| conversions.swift:67:12:67:70 | call to Float.init(sign:exponent:significand:) | conversions.swift:67:41:67:51 | call to sourceInt() | conversions.swift:67:12:67:70 | call to Float.init(sign:exponent:significand:) | result | -| conversions.swift:68:12:68:70 | call to Float.init(sign:exponent:significand:) | conversions.swift:68:57:68:69 | call to sourceFloat() | conversions.swift:68:12:68:70 | call to Float.init(sign:exponent:significand:) | result | -| conversions.swift:70:12:70:57 | call to Float.init(signOf:magnitudeOf:) | conversions.swift:70:44:70:56 | call to sourceFloat() | conversions.swift:70:12:70:57 | call to Float.init(signOf:magnitudeOf:) | result | -| conversions.swift:72:12:72:26 | .exponent | conversions.swift:72:12:72:24 | call to sourceFloat() | conversions.swift:72:12:72:26 | .exponent | result | -| conversions.swift:73:12:73:26 | .significand | conversions.swift:73:12:73:24 | call to sourceFloat() | conversions.swift:73:12:73:26 | .significand | result | -| conversions.swift:77:12:77:25 | call to sourceString() | conversions.swift:77:12:77:25 | call to sourceString() | conversions.swift:77:12:77:25 | call to sourceString() | result | -| conversions.swift:78:12:78:33 | call to String.init(_:) | conversions.swift:78:19:78:32 | call to sourceString() | conversions.swift:78:12:78:33 | call to String.init(_:) | result | -| conversions.swift:87:12:87:12 | ms2 | conversions.swift:86:21:86:34 | call to sourceString() | conversions.swift:87:12:87:12 | ms2 | result | -| conversions.swift:95:12:95:12 | parent | conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:95:12:95:12 | parent | result | -| conversions.swift:96:12:96:12 | parent | conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:96:12:96:12 | parent | result | -| conversions.swift:99:12:99:12 | v3 | conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:99:12:99:12 | v3 | result | -| conversions.swift:100:12:100:12 | v3 | conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:100:12:100:12 | v3 | result | -| conversions.swift:108:12:108:35 | call to Self.init(_:) | conversions.swift:108:24:108:34 | call to sourceInt() | conversions.swift:108:12:108:35 | call to Self.init(_:) | result | +| conversions.swift:26:12:26:22 | call to sourceInt() | conversions.swift:26:12:26:22 | call to sourceInt() | conversions.swift:26:12:26:22 | call to sourceInt() | result | +| conversions.swift:27:12:27:27 | call to Self.init(_:) | conversions.swift:27:16:27:26 | call to sourceInt() | conversions.swift:27:12:27:27 | call to Self.init(_:) | result | +| conversions.swift:28:12:28:29 | call to Self.init(_:) | conversions.swift:28:18:28:28 | call to sourceInt() | conversions.swift:28:12:28:29 | call to Self.init(_:) | result | +| conversions.swift:29:12:29:29 | call to Float.init(_:) | conversions.swift:29:18:29:28 | call to sourceInt() | conversions.swift:29:12:29:29 | call to Float.init(_:) | result | +| conversions.swift:30:12:30:30 | call to String.init(_:) | conversions.swift:30:19:30:29 | call to sourceInt() | conversions.swift:30:12:30:30 | call to String.init(_:) | result | +| conversions.swift:31:12:31:32 | .utf8 | conversions.swift:31:19:31:29 | call to sourceInt() | conversions.swift:31:12:31:32 | .utf8 | result | +| conversions.swift:35:12:35:17 | ...[...] | conversions.swift:33:19:33:29 | call to sourceInt() | conversions.swift:35:12:35:17 | ...[...] | result | +| conversions.swift:42:13:42:13 | v | conversions.swift:41:13:41:23 | call to sourceInt() | conversions.swift:42:13:42:13 | v | result | +| conversions.swift:46:12:46:12 | v2 | conversions.swift:45:30:45:40 | call to sourceInt() | conversions.swift:46:12:46:12 | v2 | result | +| conversions.swift:49:12:49:12 | v4 | conversions.swift:48:31:48:41 | call to sourceInt() | conversions.swift:49:12:49:12 | v4 | result | +| conversions.swift:52:12:52:12 | v5 | conversions.swift:51:36:51:46 | call to sourceInt() | conversions.swift:52:12:52:12 | v5 | result | +| conversions.swift:55:12:55:12 | v6 | conversions.swift:54:28:54:38 | call to sourceInt() | conversions.swift:55:12:55:12 | v6 | result | +| conversions.swift:57:12:57:37 | ...! | conversions.swift:57:25:57:35 | call to sourceInt() | conversions.swift:57:12:57:37 | ...! | result | +| conversions.swift:58:12:58:37 | call to Self.init(clamping:) | conversions.swift:58:26:58:36 | call to sourceInt() | conversions.swift:58:12:58:37 | call to Self.init(clamping:) | result | +| conversions.swift:59:12:59:47 | call to Self.init(truncatingIfNeeded:) | conversions.swift:59:36:59:46 | call to sourceInt() | conversions.swift:59:12:59:47 | call to Self.init(truncatingIfNeeded:) | result | +| conversions.swift:60:12:60:42 | ...! | conversions.swift:60:16:60:29 | call to sourceString() | conversions.swift:60:12:60:42 | ...! | result | +| conversions.swift:62:12:62:41 | call to Self.init(littleEndian:) | conversions.swift:62:30:62:40 | call to sourceInt() | conversions.swift:62:12:62:41 | call to Self.init(littleEndian:) | result | +| conversions.swift:63:12:63:38 | call to Self.init(bigEndian:) | conversions.swift:63:27:63:37 | call to sourceInt() | conversions.swift:63:12:63:38 | call to Self.init(bigEndian:) | result | +| conversions.swift:64:12:64:24 | .littleEndian | conversions.swift:64:12:64:22 | call to sourceInt() | conversions.swift:64:12:64:24 | .littleEndian | result | +| conversions.swift:65:12:65:24 | .bigEndian | conversions.swift:65:12:65:22 | call to sourceInt() | conversions.swift:65:12:65:24 | .bigEndian | result | +| conversions.swift:69:12:69:24 | call to sourceFloat() | conversions.swift:69:12:69:24 | call to sourceFloat() | conversions.swift:69:12:69:24 | call to sourceFloat() | result | +| conversions.swift:70:12:70:31 | call to Float.init(_:) | conversions.swift:70:18:70:30 | call to sourceFloat() | conversions.swift:70:12:70:31 | call to Float.init(_:) | result | +| conversions.swift:71:12:71:31 | call to UInt8.init(_:) | conversions.swift:71:18:71:30 | call to sourceFloat() | conversions.swift:71:12:71:31 | call to UInt8.init(_:) | result | +| conversions.swift:72:12:72:32 | call to String.init(_:) | conversions.swift:72:19:72:31 | call to sourceFloat() | conversions.swift:72:12:72:32 | call to String.init(_:) | result | +| conversions.swift:73:12:73:34 | .utf8 | conversions.swift:73:19:73:31 | call to sourceFloat() | conversions.swift:73:12:73:34 | .utf8 | result | +| conversions.swift:75:12:75:31 | call to Float.init(_:) | conversions.swift:75:18:75:30 | call to sourceFloat() | conversions.swift:75:12:75:31 | call to Float.init(_:) | result | +| conversions.swift:76:12:76:70 | call to Float.init(sign:exponent:significand:) | conversions.swift:76:41:76:51 | call to sourceInt() | conversions.swift:76:12:76:70 | call to Float.init(sign:exponent:significand:) | result | +| conversions.swift:77:12:77:70 | call to Float.init(sign:exponent:significand:) | conversions.swift:77:57:77:69 | call to sourceFloat() | conversions.swift:77:12:77:70 | call to Float.init(sign:exponent:significand:) | result | +| conversions.swift:79:12:79:57 | call to Float.init(signOf:magnitudeOf:) | conversions.swift:79:44:79:56 | call to sourceFloat() | conversions.swift:79:12:79:57 | call to Float.init(signOf:magnitudeOf:) | result | +| conversions.swift:81:12:81:26 | .exponent | conversions.swift:81:12:81:24 | call to sourceFloat() | conversions.swift:81:12:81:26 | .exponent | result | +| conversions.swift:82:12:82:26 | .significand | conversions.swift:82:12:82:24 | call to sourceFloat() | conversions.swift:82:12:82:26 | .significand | result | +| conversions.swift:86:12:86:25 | call to sourceString() | conversions.swift:86:12:86:25 | call to sourceString() | conversions.swift:86:12:86:25 | call to sourceString() | result | +| conversions.swift:87:12:87:33 | call to String.init(_:) | conversions.swift:87:19:87:32 | call to sourceString() | conversions.swift:87:12:87:33 | call to String.init(_:) | result | +| conversions.swift:96:12:96:12 | ms2 | conversions.swift:95:21:95:34 | call to sourceString() | conversions.swift:96:12:96:12 | ms2 | result | +| conversions.swift:104:12:104:12 | parent | conversions.swift:103:31:103:44 | call to sourceString() | conversions.swift:104:12:104:12 | parent | result | +| conversions.swift:105:12:105:12 | parent | conversions.swift:103:31:103:44 | call to sourceString() | conversions.swift:105:12:105:12 | parent | result | +| conversions.swift:108:12:108:12 | v3 | conversions.swift:103:31:103:44 | call to sourceString() | conversions.swift:108:12:108:12 | v3 | result | +| conversions.swift:109:12:109:12 | v3 | conversions.swift:103:31:103:44 | call to sourceString() | conversions.swift:109:12:109:12 | v3 | result | +| conversions.swift:117:12:117:35 | call to Self.init(_:) | conversions.swift:117:24:117:34 | call to sourceInt() | conversions.swift:117:12:117:35 | call to Self.init(_:) | result | | simple.swift:12:13:12:24 | ... .+(_:_:) ... | simple.swift:12:17:12:24 | call to source() | simple.swift:12:13:12:24 | ... .+(_:_:) ... | result | | simple.swift:13:13:13:24 | ... .+(_:_:) ... | simple.swift:13:13:13:20 | call to source() | simple.swift:13:13:13:24 | ... .+(_:_:) ... | result | | simple.swift:14:13:14:24 | ... .-(_:_:) ... | simple.swift:14:17:14:24 | call to source() | simple.swift:14:13:14:24 | ... .-(_:_:) ... | result | diff --git a/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift b/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift index 321c555e0abc..efb0bba4ed27 100644 --- a/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift +++ b/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift @@ -20,62 +20,71 @@ class MyString : LosslessStringConvertible, CustomStringConvertible, CustomDebug var clean: String { get { return "" } } } +typealias MyInt = Int + func testConversions() { - sink(arg: sourceInt()) // $ tainted=24 - sink(arg: Int(sourceInt())) // $ tainted=25 - sink(arg: UInt8(sourceInt())) // $ tainted=26 - sink(arg: Float(sourceInt())) // $ tainted=27 - sink(arg: String(sourceInt())) // $ tainted=28 - sink(arg: String(sourceInt()).utf8) // $ tainted=29 - sink(arg: [UInt8](sourceString().utf8)) // $ MISSING: tainted= + sink(arg: sourceInt()) // $ tainted=26 + sink(arg: Int(sourceInt())) // $ tainted=27 + sink(arg: UInt8(sourceInt())) // $ tainted=28 + sink(arg: Float(sourceInt())) // $ tainted=29 + sink(arg: String(sourceInt())) // $ tainted=30 + sink(arg: String(sourceInt()).utf8) // $ tainted=31 + + let arr = [1, 2, sourceInt()] + sink(arg: arr) + sink(arg: arr[0]) // $ tainted=33 + sink(arg: [MyInt](arr)) + sink(arg: [MyInt](arr)[0]) // $ MISSING: tainted=33 + sink(arg: [UInt8](sourceString().utf8)) + sink(arg: [UInt8](sourceString().utf8)[0]) // $ MISSING: tainted=33 if let v = sourceInt() as? UInt { - sink(arg: v) // $ tainted=32 + sink(arg: v) // $ tainted=41 } let v2: UInt8 = numericCast(sourceInt()) - sink(arg: v2) // $ tainted=36 + sink(arg: v2) // $ tainted=45 let v4: UInt = unsafeBitCast(sourceInt(), to: UInt.self) - sink(arg: v4) // $ tainted=39 + sink(arg: v4) // $ tainted=48 let v5 = UInt(truncatingIfNeeded: sourceInt()) - sink(arg: v5) // $ tainted=42 + sink(arg: v5) // $ tainted=51 let v6 = UInt(bitPattern: sourceInt()) - sink(arg: v6) // $ tainted=45 + sink(arg: v6) // $ tainted=54 - sink(arg: Int(exactly: sourceInt())!) // $ tainted=48 - sink(arg: Int(clamping: sourceInt())) // $ tainted=49 - sink(arg: Int(truncatingIfNeeded: sourceInt())) // $ tainted=50 - sink(arg: Int(sourceString(), radix: 10)!) // $ tainted=51 + sink(arg: Int(exactly: sourceInt())!) // $ tainted=57 + sink(arg: Int(clamping: sourceInt())) // $ tainted=58 + sink(arg: Int(truncatingIfNeeded: sourceInt())) // $ tainted=59 + sink(arg: Int(sourceString(), radix: 10)!) // $ tainted=60 - sink(arg: Int(littleEndian: sourceInt())) // $ tainted=53 - sink(arg: Int(bigEndian: sourceInt())) // $ tainted=54 - sink(arg: sourceInt().littleEndian) // $ tainted=55 - sink(arg: sourceInt().bigEndian) // $ tainted=56 + sink(arg: Int(littleEndian: sourceInt())) // $ tainted=62 + sink(arg: Int(bigEndian: sourceInt())) // $ tainted=63 + sink(arg: sourceInt().littleEndian) // $ tainted=64 + sink(arg: sourceInt().bigEndian) // $ tainted=65 // --- - sink(arg: sourceFloat()) // $ tainted=60 - sink(arg: Float(sourceFloat())) // $ tainted=61 - sink(arg: UInt8(sourceFloat())) // $ tainted=62 - sink(arg: String(sourceFloat())) // $ tainted=63 - sink(arg: String(sourceFloat()).utf8) // $ tainted=64 + sink(arg: sourceFloat()) // $ tainted=69 + sink(arg: Float(sourceFloat())) // $ tainted=70 + sink(arg: UInt8(sourceFloat())) // $ tainted=71 + sink(arg: String(sourceFloat())) // $ tainted=72 + sink(arg: String(sourceFloat()).utf8) // $ tainted=73 - sink(arg: Float(sourceFloat())) // $ tainted=66 - sink(arg: Float(sign: .plus, exponent: sourceInt(), significand: 0.0)) // $ tainted=67 - sink(arg: Float(sign: .plus, exponent: 0, significand: sourceFloat())) // $ tainted=68 + sink(arg: Float(sourceFloat())) // $ tainted=75 + sink(arg: Float(sign: .plus, exponent: sourceInt(), significand: 0.0)) // $ tainted=76 + sink(arg: Float(sign: .plus, exponent: 0, significand: sourceFloat())) // $ tainted=77 sink(arg: Float(signOf: sourceFloat(), magnitudeOf: 0.0)) // (good) - sink(arg: Float(signOf: 0.0, magnitudeOf: sourceFloat())) // $ tainted=70 + sink(arg: Float(signOf: 0.0, magnitudeOf: sourceFloat())) // $ tainted=79 - sink(arg: sourceFloat().exponent) // $ tainted=72 - sink(arg: sourceFloat().significand) // $ tainted=73 + sink(arg: sourceFloat().exponent) // $ tainted=81 + sink(arg: sourceFloat().significand) // $ tainted=82 // --- - sink(arg: sourceString()) // $ tainted=77 - sink(arg: String(sourceString())) // $ tainted=78 + sink(arg: sourceString()) // $ tainted=86 + sink(arg: String(sourceString())) // $ tainted=87 let ms1 = MyString("abc")! sink(arg: ms1) @@ -84,7 +93,7 @@ func testConversions() { sink(arg: ms1.clean) let ms2 = MyString(sourceString())! - sink(arg: ms2) // $ tainted=86 + sink(arg: ms2) // $ tainted=95 sink(arg: ms2.description) // $ MISSING: tainted= sink(arg: ms2.debugDescription) // $ MISSING: tainted= sink(arg: ms2.clean) @@ -92,12 +101,12 @@ func testConversions() { // --- let parent : MyParentClass = sourceString() as! MyChildClass - sink(arg: parent) // $ tainted=94 - sink(arg: parent as! MyChildClass) // $ tainted=94 + sink(arg: parent) // $ tainted=103 + sink(arg: parent as! MyChildClass) // $ tainted=103 let v3: MyChildClass = unsafeDowncast(parent, to: MyChildClass.self) - sink(arg: v3) // $ tainted=94 - sink(arg: v3 as! MyParentClass) // $ tainted=94 + sink(arg: v3) // $ tainted=103 + sink(arg: v3 as! MyParentClass) // $ tainted=103 } var myCEnumConst : Int = 0 @@ -105,5 +114,5 @@ typealias MyCEnumType = UInt32 func testCEnum() { sink(arg: MyCEnumType(myCEnumConst)) - sink(arg: MyCEnumType(sourceInt())) // $ tainted=108 + sink(arg: MyCEnumType(sourceInt())) // $ tainted=117 } From 4b66bada3d188fc891950b1171ae9b3abb572323 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 16 Aug 2023 12:01:53 +0100 Subject: [PATCH 09/20] Swift: Model array initializers. --- .../swift/frameworks/StandardLibrary/Array.qll | 5 +++++ .../dataflow/taint/core/Taint.expected | 15 +++++++++++++++ .../dataflow/taint/core/conversions.swift | 4 ++-- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Array.qll b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Array.qll index 207d120e82e1..30d753ae967e 100644 --- a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Array.qll +++ b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Array.qll @@ -19,6 +19,11 @@ private class ArraySummaries extends SummaryModelCsv { override predicate row(string row) { row = [ + ";Array;true;init(_:);;;Argument[0];ReturnValue.ArrayElement;value", + ";Array;true;init(_:);;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value", + ";Array;true;init(_:);;;Argument[0].CollectionElement;ReturnValue.ArrayElement;value", + ";Array;true;init(repeating:count:);;;Argument[0];ReturnValue.ArrayElement;value", + ";Array;true;init(arrayLiteral:);;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value", ";Array;true;insert(_:at:);;;Argument[0];Argument[-1].ArrayElement;value", ";Array;true;insert(_:at:);;;Argument[1];Argument[-1];taint" ] diff --git a/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected b/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected index 4f10e907be3c..440a286dfb90 100644 --- a/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected @@ -6,8 +6,14 @@ edges | conversions.swift:31:12:31:30 | call to String.init(_:) | conversions.swift:31:12:31:32 | .utf8 | | conversions.swift:31:19:31:29 | call to sourceInt() | conversions.swift:31:12:31:30 | call to String.init(_:) | | conversions.swift:33:12:33:30 | [...] [Array element] | conversions.swift:35:12:35:12 | arr [Array element] | +| conversions.swift:33:12:33:30 | [...] [Array element] | conversions.swift:37:20:37:20 | arr [Array element] | | conversions.swift:33:19:33:29 | call to sourceInt() | conversions.swift:33:12:33:30 | [...] [Array element] | | conversions.swift:35:12:35:12 | arr [Array element] | conversions.swift:35:12:35:17 | ...[...] | +| conversions.swift:37:12:37:23 | call to Array.init(_:) [Array element] | conversions.swift:37:12:37:26 | ...[...] | +| conversions.swift:37:20:37:20 | arr [Array element] | conversions.swift:37:12:37:23 | call to Array.init(_:) [Array element] | +| conversions.swift:39:12:39:39 | call to Array.init(_:) [Array element] | conversions.swift:39:12:39:42 | ...[...] | +| conversions.swift:39:20:39:33 | call to sourceString() | conversions.swift:39:20:39:35 | .utf8 | +| conversions.swift:39:20:39:35 | .utf8 | conversions.swift:39:12:39:39 | call to Array.init(_:) [Array element] | | conversions.swift:41:13:41:23 | call to sourceInt() | conversions.swift:42:13:42:13 | v | | conversions.swift:45:18:45:41 | call to numericCast(_:) | conversions.swift:46:12:46:12 | v2 | | conversions.swift:45:30:45:40 | call to sourceInt() | conversions.swift:45:18:45:41 | call to numericCast(_:) | @@ -145,6 +151,13 @@ nodes | conversions.swift:33:19:33:29 | call to sourceInt() | semmle.label | call to sourceInt() | | conversions.swift:35:12:35:12 | arr [Array element] | semmle.label | arr [Array element] | | conversions.swift:35:12:35:17 | ...[...] | semmle.label | ...[...] | +| conversions.swift:37:12:37:23 | call to Array.init(_:) [Array element] | semmle.label | call to Array.init(_:) [Array element] | +| conversions.swift:37:12:37:26 | ...[...] | semmle.label | ...[...] | +| conversions.swift:37:20:37:20 | arr [Array element] | semmle.label | arr [Array element] | +| conversions.swift:39:12:39:39 | call to Array.init(_:) [Array element] | semmle.label | call to Array.init(_:) [Array element] | +| conversions.swift:39:12:39:42 | ...[...] | semmle.label | ...[...] | +| conversions.swift:39:20:39:33 | call to sourceString() | semmle.label | call to sourceString() | +| conversions.swift:39:20:39:35 | .utf8 | semmle.label | .utf8 | | conversions.swift:41:13:41:23 | call to sourceInt() | semmle.label | call to sourceInt() | | conversions.swift:42:13:42:13 | v | semmle.label | v | | conversions.swift:45:18:45:41 | call to numericCast(_:) | semmle.label | call to numericCast(_:) | @@ -346,6 +359,8 @@ subpaths | conversions.swift:30:12:30:30 | call to String.init(_:) | conversions.swift:30:19:30:29 | call to sourceInt() | conversions.swift:30:12:30:30 | call to String.init(_:) | result | | conversions.swift:31:12:31:32 | .utf8 | conversions.swift:31:19:31:29 | call to sourceInt() | conversions.swift:31:12:31:32 | .utf8 | result | | conversions.swift:35:12:35:17 | ...[...] | conversions.swift:33:19:33:29 | call to sourceInt() | conversions.swift:35:12:35:17 | ...[...] | result | +| conversions.swift:37:12:37:26 | ...[...] | conversions.swift:33:19:33:29 | call to sourceInt() | conversions.swift:37:12:37:26 | ...[...] | result | +| conversions.swift:39:12:39:42 | ...[...] | conversions.swift:39:20:39:33 | call to sourceString() | conversions.swift:39:12:39:42 | ...[...] | result | | conversions.swift:42:13:42:13 | v | conversions.swift:41:13:41:23 | call to sourceInt() | conversions.swift:42:13:42:13 | v | result | | conversions.swift:46:12:46:12 | v2 | conversions.swift:45:30:45:40 | call to sourceInt() | conversions.swift:46:12:46:12 | v2 | result | | conversions.swift:49:12:49:12 | v4 | conversions.swift:48:31:48:41 | call to sourceInt() | conversions.swift:49:12:49:12 | v4 | result | diff --git a/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift b/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift index efb0bba4ed27..e24c8347251a 100644 --- a/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift +++ b/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift @@ -34,9 +34,9 @@ func testConversions() { sink(arg: arr) sink(arg: arr[0]) // $ tainted=33 sink(arg: [MyInt](arr)) - sink(arg: [MyInt](arr)[0]) // $ MISSING: tainted=33 + sink(arg: [MyInt](arr)[0]) // $ tainted=33 sink(arg: [UInt8](sourceString().utf8)) - sink(arg: [UInt8](sourceString().utf8)[0]) // $ MISSING: tainted=33 + sink(arg: [UInt8](sourceString().utf8)[0]) // $ tainted=39 if let v = sourceInt() as? UInt { sink(arg: v) // $ tainted=41 From 311daa253945f945fff9682d265f980a84a9f673 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 19 Sep 2023 10:39:59 +0100 Subject: [PATCH 10/20] Swift: Accept fixed test case having merged in main. --- .../library-tests/dataflow/dataflow/DataFlowInline.expected | 1 - swift/ql/test/library-tests/dataflow/dataflow/test.swift | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/swift/ql/test/library-tests/dataflow/dataflow/DataFlowInline.expected b/swift/ql/test/library-tests/dataflow/dataflow/DataFlowInline.expected index 75cfac32cc24..48de9172b362 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/DataFlowInline.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/DataFlowInline.expected @@ -1,3 +1,2 @@ failures testFailures -| test.swift:709:15:709:21 | ...[...] | Fixed missing result:flow=708 | diff --git a/swift/ql/test/library-tests/dataflow/dataflow/test.swift b/swift/ql/test/library-tests/dataflow/dataflow/test.swift index d3dc57f8ef1c..a4bed4bcf7e8 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/test.swift +++ b/swift/ql/test/library-tests/dataflow/dataflow/test.swift @@ -706,7 +706,7 @@ func testArray() { sink(arg: arr4[0]) // $ MISSING: flow=692 var arr5 = Array(repeating: source(), count: 2) - sink(arg: arr5[0]) // $ MISSING: flow=708 + sink(arg: arr5[0]) // $ flow=708 var arr6 = [1,2,3] arr6.insert(source(), at: 2) From 2d05b85bb49d01d3f1cca8468a3e47fb5f0b2c89 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 19 Sep 2023 10:45:37 +0100 Subject: [PATCH 11/20] Swift: Fix uses of legacy CArrayElement. --- .../frameworks/StandardLibrary/Array.qll | 9 +++---- .../frameworks/StandardLibrary/CInterop.qll | 2 +- .../dataflow/taint/core/Taint.expected | 26 +++++++++---------- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Array.qll b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Array.qll index 168d7af67b03..007647bf01ec 100644 --- a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Array.qll +++ b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Array.qll @@ -19,11 +19,10 @@ private class ArraySummaries extends SummaryModelCsv { override predicate row(string row) { row = [ - ";Array;true;init(_:);;;Argument[0];ReturnValue.ArrayElement;value", - ";Array;true;init(_:);;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value", - ";Array;true;init(_:);;;Argument[0].CollectionElement;ReturnValue.ArrayElement;value", - ";Array;true;init(repeating:count:);;;Argument[0];ReturnValue.ArrayElement;value", - ";Array;true;init(arrayLiteral:);;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value", + ";Array;true;init(_:);;;Argument[0];ReturnValue.CollectionElement;value", + ";Array;true;init(_:);;;Argument[0].CollectionElement;ReturnValue.CollectionElement;value", + ";Array;true;init(repeating:count:);;;Argument[0];ReturnValue.CollectionElement;value", + ";Array;true;init(arrayLiteral:);;;Argument[0].CollectionElement;ReturnValue.CollectionElement;value", ";Array;true;insert(_:at:);;;Argument[0];Argument[-1].CollectionElement;value", ";Array;true;insert(_:at:);;;Argument[1];Argument[-1];taint", ";Array;true;withUnsafeBufferPointer(_:);;;Argument[-1];Argument[0].Parameter[0].CollectionElement;taint", diff --git a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/CInterop.qll b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/CInterop.qll index ac7d5c5b67e5..35a7cafe1e94 100644 --- a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/CInterop.qll +++ b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/CInterop.qll @@ -7,6 +7,6 @@ private import codeql.swift.dataflow.ExternalFlow private class CInteropSummaries extends SummaryModelCsv { override predicate row(string row) { - row = ";;false;getVaList(_:);;;Argument[0].ArrayElement;ReturnValue;value" + row = ";;false;getVaList(_:);;;Argument[0].CollectionElement;ReturnValue;value" } } diff --git a/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected b/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected index 440a286dfb90..2fcfd5c16eb4 100644 --- a/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected @@ -5,15 +5,15 @@ edges | conversions.swift:30:19:30:29 | call to sourceInt() | conversions.swift:30:12:30:30 | call to String.init(_:) | | conversions.swift:31:12:31:30 | call to String.init(_:) | conversions.swift:31:12:31:32 | .utf8 | | conversions.swift:31:19:31:29 | call to sourceInt() | conversions.swift:31:12:31:30 | call to String.init(_:) | -| conversions.swift:33:12:33:30 | [...] [Array element] | conversions.swift:35:12:35:12 | arr [Array element] | -| conversions.swift:33:12:33:30 | [...] [Array element] | conversions.swift:37:20:37:20 | arr [Array element] | -| conversions.swift:33:19:33:29 | call to sourceInt() | conversions.swift:33:12:33:30 | [...] [Array element] | -| conversions.swift:35:12:35:12 | arr [Array element] | conversions.swift:35:12:35:17 | ...[...] | -| conversions.swift:37:12:37:23 | call to Array.init(_:) [Array element] | conversions.swift:37:12:37:26 | ...[...] | -| conversions.swift:37:20:37:20 | arr [Array element] | conversions.swift:37:12:37:23 | call to Array.init(_:) [Array element] | -| conversions.swift:39:12:39:39 | call to Array.init(_:) [Array element] | conversions.swift:39:12:39:42 | ...[...] | +| conversions.swift:33:12:33:30 | [...] [Collection element] | conversions.swift:35:12:35:12 | arr [Collection element] | +| conversions.swift:33:12:33:30 | [...] [Collection element] | conversions.swift:37:20:37:20 | arr [Collection element] | +| conversions.swift:33:19:33:29 | call to sourceInt() | conversions.swift:33:12:33:30 | [...] [Collection element] | +| conversions.swift:35:12:35:12 | arr [Collection element] | conversions.swift:35:12:35:17 | ...[...] | +| conversions.swift:37:12:37:23 | call to Array.init(_:) [Collection element] | conversions.swift:37:12:37:26 | ...[...] | +| conversions.swift:37:20:37:20 | arr [Collection element] | conversions.swift:37:12:37:23 | call to Array.init(_:) [Collection element] | +| conversions.swift:39:12:39:39 | call to Array.init(_:) [Collection element] | conversions.swift:39:12:39:42 | ...[...] | | conversions.swift:39:20:39:33 | call to sourceString() | conversions.swift:39:20:39:35 | .utf8 | -| conversions.swift:39:20:39:35 | .utf8 | conversions.swift:39:12:39:39 | call to Array.init(_:) [Array element] | +| conversions.swift:39:20:39:35 | .utf8 | conversions.swift:39:12:39:39 | call to Array.init(_:) [Collection element] | | conversions.swift:41:13:41:23 | call to sourceInt() | conversions.swift:42:13:42:13 | v | | conversions.swift:45:18:45:41 | call to numericCast(_:) | conversions.swift:46:12:46:12 | v2 | | conversions.swift:45:30:45:40 | call to sourceInt() | conversions.swift:45:18:45:41 | call to numericCast(_:) | @@ -147,14 +147,14 @@ nodes | conversions.swift:31:12:31:30 | call to String.init(_:) | semmle.label | call to String.init(_:) | | conversions.swift:31:12:31:32 | .utf8 | semmle.label | .utf8 | | conversions.swift:31:19:31:29 | call to sourceInt() | semmle.label | call to sourceInt() | -| conversions.swift:33:12:33:30 | [...] [Array element] | semmle.label | [...] [Array element] | +| conversions.swift:33:12:33:30 | [...] [Collection element] | semmle.label | [...] [Collection element] | | conversions.swift:33:19:33:29 | call to sourceInt() | semmle.label | call to sourceInt() | -| conversions.swift:35:12:35:12 | arr [Array element] | semmle.label | arr [Array element] | +| conversions.swift:35:12:35:12 | arr [Collection element] | semmle.label | arr [Collection element] | | conversions.swift:35:12:35:17 | ...[...] | semmle.label | ...[...] | -| conversions.swift:37:12:37:23 | call to Array.init(_:) [Array element] | semmle.label | call to Array.init(_:) [Array element] | +| conversions.swift:37:12:37:23 | call to Array.init(_:) [Collection element] | semmle.label | call to Array.init(_:) [Collection element] | | conversions.swift:37:12:37:26 | ...[...] | semmle.label | ...[...] | -| conversions.swift:37:20:37:20 | arr [Array element] | semmle.label | arr [Array element] | -| conversions.swift:39:12:39:39 | call to Array.init(_:) [Array element] | semmle.label | call to Array.init(_:) [Array element] | +| conversions.swift:37:20:37:20 | arr [Collection element] | semmle.label | arr [Collection element] | +| conversions.swift:39:12:39:39 | call to Array.init(_:) [Collection element] | semmle.label | call to Array.init(_:) [Collection element] | | conversions.swift:39:12:39:42 | ...[...] | semmle.label | ...[...] | | conversions.swift:39:20:39:33 | call to sourceString() | semmle.label | call to sourceString() | | conversions.swift:39:20:39:35 | .utf8 | semmle.label | .utf8 | From 48d1b667cf75fc77794cd4d1ac28bb168f7aa2ab Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 19 Sep 2023 11:22:12 +0100 Subject: [PATCH 12/20] Swift: Autoformat. --- .../lib/codeql/swift/frameworks/StandardLibrary/Numeric.qll | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Numeric.qll b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Numeric.qll index a985bb7f0ed4..904982846c03 100644 --- a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Numeric.qll +++ b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Numeric.qll @@ -46,6 +46,8 @@ private class NumericFieldsInheritTaint extends TaintInheritingContent, NumericFieldsInheritTaint() { this.getField().hasQualifiedName("FixedWidthInteger", ["littleEndian", "bigEndian"]) or - this.getField().hasQualifiedName(["Double", "Float", "Float80", "FloatingPoint"], ["exponent", "significand"]) + this.getField() + .hasQualifiedName(["Double", "Float", "Float80", "FloatingPoint"], + ["exponent", "significand"]) } } From 158008ac4ff3627aeaa617fff0491302ca6a1f2d Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 19 Sep 2023 13:08:08 +0100 Subject: [PATCH 13/20] Swift: New results in tests. --- .../Security/CWE-078/CommandInjection.expected | 9 +++++++++ .../query-tests/Security/CWE-089/SQLite.swift | 2 +- .../Security/CWE-089/SqlInjection.expected | 14 ++++++++++++++ .../Security/CWE-089/sqlite3_c_api.swift | 2 +- .../Security/CWE-094/UnsafeJsEval.expected | 16 ++++++++++++++++ .../CWE-134/UncontrolledFormatString.expected | 18 ++++++++++++++++++ .../CWE-134/UncontrolledFormatString.swift | 4 ++-- 7 files changed, 61 insertions(+), 4 deletions(-) diff --git a/swift/ql/test/query-tests/Security/CWE-078/CommandInjection.expected b/swift/ql/test/query-tests/Security/CWE-078/CommandInjection.expected index a015cb69b644..5d4c4a63b587 100644 --- a/swift/ql/test/query-tests/Security/CWE-078/CommandInjection.expected +++ b/swift/ql/test/query-tests/Security/CWE-078/CommandInjection.expected @@ -7,9 +7,11 @@ edges | CommandInjection.swift:69:12:69:12 | userControlledString | CommandInjection.swift:75:27:75:27 | userControlledString | | CommandInjection.swift:69:12:69:12 | userControlledString [some:0] | CommandInjection.swift:75:27:75:27 | userControlledString [some:0] | | CommandInjection.swift:69:40:69:94 | call to String.init(contentsOf:) | CommandInjection.swift:69:40:69:94 | call to String.init(contentsOf:) [some:0] | +| CommandInjection.swift:69:40:69:94 | call to String.init(contentsOf:) | CommandInjection.swift:75:27:75:27 | userControlledString | | CommandInjection.swift:69:40:69:94 | call to String.init(contentsOf:) [some:0, some:0] | CommandInjection.swift:69:8:69:12 | let ...? [some:0, some:0] | | CommandInjection.swift:69:40:69:94 | call to String.init(contentsOf:) [some:0] | CommandInjection.swift:69:8:69:12 | let ...? [some:0] | | CommandInjection.swift:69:40:69:94 | call to String.init(contentsOf:) [some:0] | CommandInjection.swift:69:40:69:94 | call to String.init(contentsOf:) [some:0, some:0] | +| CommandInjection.swift:69:40:69:94 | call to String.init(contentsOf:) [some:0] | CommandInjection.swift:75:27:75:27 | userControlledString [some:0] | | CommandInjection.swift:75:2:75:2 | [post] task1 [arguments] | CommandInjection.swift:75:2:75:2 | [post] task1 | | CommandInjection.swift:75:20:75:47 | [...] | CommandInjection.swift:75:2:75:2 | [post] task1 [arguments] | | CommandInjection.swift:75:27:75:27 | userControlledString | CommandInjection.swift:75:20:75:47 | [...] | @@ -17,8 +19,10 @@ edges | CommandInjection.swift:75:27:75:27 | userControlledString [some:0] | CommandInjection.swift:78:43:78:43 | userControlledString [some:0] | | CommandInjection.swift:78:5:78:9 | let ...? [some:0] | CommandInjection.swift:78:9:78:9 | validatedString | | CommandInjection.swift:78:9:78:9 | validatedString | CommandInjection.swift:81:31:81:31 | validatedString | +| CommandInjection.swift:78:27:78:63 | call to validateCommand(_:) | CommandInjection.swift:81:31:81:31 | validatedString | | CommandInjection.swift:78:27:78:63 | call to validateCommand(_:) [some:0] | CommandInjection.swift:78:5:78:9 | let ...? [some:0] | | CommandInjection.swift:78:43:78:43 | userControlledString | CommandInjection.swift:58:22:58:33 | command | +| CommandInjection.swift:78:43:78:43 | userControlledString | CommandInjection.swift:78:27:78:63 | call to validateCommand(_:) | | CommandInjection.swift:78:43:78:43 | userControlledString | CommandInjection.swift:78:27:78:63 | call to validateCommand(_:) [some:0] | | CommandInjection.swift:78:43:78:43 | userControlledString [some:0] | CommandInjection.swift:58:22:58:33 | command [some:0] | | CommandInjection.swift:78:43:78:43 | userControlledString [some:0] | CommandInjection.swift:78:27:78:63 | call to validateCommand(_:) [some:0] | @@ -29,6 +33,8 @@ edges | CommandInjection.swift:99:12:99:12 | userControlledString | CommandInjection.swift:114:36:114:36 | userControlledString | | CommandInjection.swift:99:12:99:12 | userControlledString | CommandInjection.swift:115:28:115:28 | userControlledString | | CommandInjection.swift:99:40:99:94 | call to String.init(contentsOf:) | CommandInjection.swift:99:40:99:94 | call to String.init(contentsOf:) [some:0] | +| CommandInjection.swift:99:40:99:94 | call to String.init(contentsOf:) | CommandInjection.swift:114:36:114:36 | userControlledString | +| CommandInjection.swift:99:40:99:94 | call to String.init(contentsOf:) | CommandInjection.swift:115:28:115:28 | userControlledString | | CommandInjection.swift:99:40:99:94 | call to String.init(contentsOf:) [some:0] | CommandInjection.swift:99:8:99:12 | let ...? [some:0] | | CommandInjection.swift:114:2:114:2 | [post] task3 [executableURL] | CommandInjection.swift:114:2:114:2 | [post] task3 | | CommandInjection.swift:114:24:114:56 | call to URL.init(string:) [some:0] | CommandInjection.swift:114:24:114:57 | ...! | @@ -90,6 +96,7 @@ edges | CommandInjection.swift:180:9:180:13 | let ...? [some:0] | CommandInjection.swift:180:13:180:13 | userControlledString | | CommandInjection.swift:180:13:180:13 | userControlledString | CommandInjection.swift:184:19:184:19 | userControlledString | | CommandInjection.swift:180:41:180:95 | call to String.init(contentsOf:) | CommandInjection.swift:180:41:180:95 | call to String.init(contentsOf:) [some:0] | +| CommandInjection.swift:180:41:180:95 | call to String.init(contentsOf:) | CommandInjection.swift:184:19:184:19 | userControlledString | | CommandInjection.swift:180:41:180:95 | call to String.init(contentsOf:) [some:0] | CommandInjection.swift:180:9:180:13 | let ...? [some:0] | | CommandInjection.swift:184:18:184:39 | [...] | CommandInjection.swift:186:18:186:18 | tainted1 | | CommandInjection.swift:184:18:184:39 | [...] | CommandInjection.swift:187:19:187:19 | tainted1 | @@ -139,6 +146,7 @@ nodes | CommandInjection.swift:75:27:75:27 | userControlledString [some:0] | semmle.label | userControlledString [some:0] | | CommandInjection.swift:78:5:78:9 | let ...? [some:0] | semmle.label | let ...? [some:0] | | CommandInjection.swift:78:9:78:9 | validatedString | semmle.label | validatedString | +| CommandInjection.swift:78:27:78:63 | call to validateCommand(_:) | semmle.label | call to validateCommand(_:) | | CommandInjection.swift:78:27:78:63 | call to validateCommand(_:) [some:0] | semmle.label | call to validateCommand(_:) [some:0] | | CommandInjection.swift:78:43:78:43 | userControlledString | semmle.label | userControlledString | | CommandInjection.swift:78:43:78:43 | userControlledString [some:0] | semmle.label | userControlledString [some:0] | @@ -240,6 +248,7 @@ nodes | file://:0:0:0:0 | url | semmle.label | url | | file://:0:0:0:0 | url | semmle.label | url | subpaths +| CommandInjection.swift:78:43:78:43 | userControlledString | CommandInjection.swift:58:22:58:33 | command | CommandInjection.swift:62:16:62:16 | command | CommandInjection.swift:78:27:78:63 | call to validateCommand(_:) | | CommandInjection.swift:78:43:78:43 | userControlledString | CommandInjection.swift:58:22:58:33 | command | CommandInjection.swift:62:16:62:16 | command [some:0] | CommandInjection.swift:78:27:78:63 | call to validateCommand(_:) [some:0] | | CommandInjection.swift:78:43:78:43 | userControlledString [some:0] | CommandInjection.swift:58:22:58:33 | command [some:0] | CommandInjection.swift:62:16:62:16 | command [some:0] | CommandInjection.swift:78:27:78:63 | call to validateCommand(_:) [some:0] | #select diff --git a/swift/ql/test/query-tests/Security/CWE-089/SQLite.swift b/swift/ql/test/query-tests/Security/CWE-089/SQLite.swift index f9a6b41340ce..7746c02a9d56 100644 --- a/swift/ql/test/query-tests/Security/CWE-089/SQLite.swift +++ b/swift/ql/test/query-tests/Security/CWE-089/SQLite.swift @@ -74,7 +74,7 @@ func test_sqlite_swift_api(db: Connection) throws { try db.execute(unsafeQuery2) // BAD try db.execute(unsafeQuery3) // BAD try db.execute(safeQuery1) // GOOD - try db.execute(safeQuery2) // GOOD + try db.execute(safeQuery2) // GOOD [FALSE POSITIVE] // --- prepared statements --- diff --git a/swift/ql/test/query-tests/Security/CWE-089/SqlInjection.expected b/swift/ql/test/query-tests/Security/CWE-089/SqlInjection.expected index a4617e9b8114..65b3383cdef5 100644 --- a/swift/ql/test/query-tests/Security/CWE-089/SqlInjection.expected +++ b/swift/ql/test/query-tests/Security/CWE-089/SqlInjection.expected @@ -82,6 +82,7 @@ edges | GRDB.swift:342:26:342:80 | call to String.init(contentsOf:) | GRDB.swift:349:84:349:84 | remoteString | | GRDB.swift:342:26:342:80 | call to String.init(contentsOf:) | GRDB.swift:350:69:350:69 | remoteString | | GRDB.swift:342:26:342:80 | call to String.init(contentsOf:) | GRDB.swift:351:84:351:84 | remoteString | +| SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:63:25:63:25 | remoteString | | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:73:17:73:17 | unsafeQuery1 | | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:74:17:74:17 | unsafeQuery2 | | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:75:17:75:17 | unsafeQuery3 | @@ -97,6 +98,9 @@ edges | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:117:16:117:16 | unsafeQuery1 | | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:119:16:119:16 | unsafeQuery1 | | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:132:20:132:20 | remoteString | +| SQLite.swift:63:21:63:37 | call to Self.init(_:) | SQLite.swift:77:17:77:17 | safeQuery2 | +| SQLite.swift:63:25:63:25 | remoteString | SQLite.swift:63:21:63:37 | call to Self.init(_:) | +| sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:123:25:123:25 | remoteString | | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:133:33:133:33 | unsafeQuery1 | | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:134:33:134:33 | unsafeQuery2 | | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:135:33:135:33 | unsafeQuery3 | @@ -104,6 +108,8 @@ edges | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:175:29:175:29 | unsafeQuery3 | | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:183:29:183:29 | unsafeQuery3 | | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:189:13:189:13 | unsafeQuery3 | +| sqlite3_c_api.swift:123:21:123:37 | call to Self.init(_:) | sqlite3_c_api.swift:137:33:137:33 | safeQuery2 | +| sqlite3_c_api.swift:123:25:123:25 | remoteString | sqlite3_c_api.swift:123:21:123:37 | call to Self.init(_:) | | sqlite3_c_api.swift:189:13:189:13 | unsafeQuery3 | sqlite3_c_api.swift:189:13:189:58 | call to data(using:allowLossyConversion:) | | sqlite3_c_api.swift:189:13:189:58 | call to data(using:allowLossyConversion:) | sqlite3_c_api.swift:190:2:190:2 | data | | sqlite3_c_api.swift:190:2:190:2 | data | sqlite3_c_api.swift:190:21:190:21 | [post] buffer | @@ -207,9 +213,12 @@ nodes | GRDB.swift:350:69:350:69 | remoteString | semmle.label | remoteString | | GRDB.swift:351:84:351:84 | remoteString | semmle.label | remoteString | | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | semmle.label | call to String.init(contentsOf:) | +| SQLite.swift:63:21:63:37 | call to Self.init(_:) | semmle.label | call to Self.init(_:) | +| SQLite.swift:63:25:63:25 | remoteString | semmle.label | remoteString | | SQLite.swift:73:17:73:17 | unsafeQuery1 | semmle.label | unsafeQuery1 | | SQLite.swift:74:17:74:17 | unsafeQuery2 | semmle.label | unsafeQuery2 | | SQLite.swift:75:17:75:17 | unsafeQuery3 | semmle.label | unsafeQuery3 | +| SQLite.swift:77:17:77:17 | safeQuery2 | semmle.label | safeQuery2 | | SQLite.swift:83:29:83:29 | unsafeQuery3 | semmle.label | unsafeQuery3 | | SQLite.swift:95:32:95:32 | remoteString | semmle.label | remoteString | | SQLite.swift:100:29:100:29 | unsafeQuery1 | semmle.label | unsafeQuery1 | @@ -223,9 +232,12 @@ nodes | SQLite.swift:119:16:119:16 | unsafeQuery1 | semmle.label | unsafeQuery1 | | SQLite.swift:132:20:132:20 | remoteString | semmle.label | remoteString | | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | semmle.label | call to String.init(contentsOf:) | +| sqlite3_c_api.swift:123:21:123:37 | call to Self.init(_:) | semmle.label | call to Self.init(_:) | +| sqlite3_c_api.swift:123:25:123:25 | remoteString | semmle.label | remoteString | | sqlite3_c_api.swift:133:33:133:33 | unsafeQuery1 | semmle.label | unsafeQuery1 | | sqlite3_c_api.swift:134:33:134:33 | unsafeQuery2 | semmle.label | unsafeQuery2 | | sqlite3_c_api.swift:135:33:135:33 | unsafeQuery3 | semmle.label | unsafeQuery3 | +| sqlite3_c_api.swift:137:33:137:33 | safeQuery2 | semmle.label | safeQuery2 | | sqlite3_c_api.swift:145:26:145:26 | unsafeQuery3 | semmle.label | unsafeQuery3 | | sqlite3_c_api.swift:175:29:175:29 | unsafeQuery3 | semmle.label | unsafeQuery3 | | sqlite3_c_api.swift:183:29:183:29 | unsafeQuery3 | semmle.label | unsafeQuery3 | @@ -324,6 +336,7 @@ subpaths | SQLite.swift:73:17:73:17 | unsafeQuery1 | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:73:17:73:17 | unsafeQuery1 | This query depends on a $@. | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | user-provided value | | SQLite.swift:74:17:74:17 | unsafeQuery2 | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:74:17:74:17 | unsafeQuery2 | This query depends on a $@. | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | user-provided value | | SQLite.swift:75:17:75:17 | unsafeQuery3 | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:75:17:75:17 | unsafeQuery3 | This query depends on a $@. | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | user-provided value | +| SQLite.swift:77:17:77:17 | safeQuery2 | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:77:17:77:17 | safeQuery2 | This query depends on a $@. | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | user-provided value | | SQLite.swift:83:29:83:29 | unsafeQuery3 | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:83:29:83:29 | unsafeQuery3 | This query depends on a $@. | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | user-provided value | | SQLite.swift:95:32:95:32 | remoteString | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:95:32:95:32 | remoteString | This query depends on a $@. | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | user-provided value | | SQLite.swift:100:29:100:29 | unsafeQuery1 | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:100:29:100:29 | unsafeQuery1 | This query depends on a $@. | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | user-provided value | @@ -339,6 +352,7 @@ subpaths | sqlite3_c_api.swift:133:33:133:33 | unsafeQuery1 | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:133:33:133:33 | unsafeQuery1 | This query depends on a $@. | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | user-provided value | | sqlite3_c_api.swift:134:33:134:33 | unsafeQuery2 | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:134:33:134:33 | unsafeQuery2 | This query depends on a $@. | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | user-provided value | | sqlite3_c_api.swift:135:33:135:33 | unsafeQuery3 | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:135:33:135:33 | unsafeQuery3 | This query depends on a $@. | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | user-provided value | +| sqlite3_c_api.swift:137:33:137:33 | safeQuery2 | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:137:33:137:33 | safeQuery2 | This query depends on a $@. | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | user-provided value | | sqlite3_c_api.swift:145:26:145:26 | unsafeQuery3 | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:145:26:145:26 | unsafeQuery3 | This query depends on a $@. | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | user-provided value | | sqlite3_c_api.swift:175:29:175:29 | unsafeQuery3 | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:175:29:175:29 | unsafeQuery3 | This query depends on a $@. | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | user-provided value | | sqlite3_c_api.swift:183:29:183:29 | unsafeQuery3 | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:183:29:183:29 | unsafeQuery3 | This query depends on a $@. | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | user-provided value | diff --git a/swift/ql/test/query-tests/Security/CWE-089/sqlite3_c_api.swift b/swift/ql/test/query-tests/Security/CWE-089/sqlite3_c_api.swift index 8498d89d68da..06846cd2072f 100644 --- a/swift/ql/test/query-tests/Security/CWE-089/sqlite3_c_api.swift +++ b/swift/ql/test/query-tests/Security/CWE-089/sqlite3_c_api.swift @@ -134,7 +134,7 @@ func test_sqlite3_c_api(db: OpaquePointer?, buffer: UnsafeMutablePointer) let result2 = sqlite3_exec(db, unsafeQuery2, nil, nil, nil) // BAD let result3 = sqlite3_exec(db, unsafeQuery3, nil, nil, nil) // BAD let result4 = sqlite3_exec(db, safeQuery1, nil, nil, nil) // GOOD - let result5 = sqlite3_exec(db, safeQuery2, nil, nil, nil) // GOOD + let result5 = sqlite3_exec(db, safeQuery2, nil, nil, nil) // GOOD [FALSE POSITIVE] // --- prepared statements --- diff --git a/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected b/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected index da56e96c094a..fa14ba0ccdd8 100644 --- a/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected +++ b/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected @@ -4,6 +4,7 @@ edges | UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() | UnsafeJsEval.swift:205:7:205:7 | remoteString | | UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() | UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... | | UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() | UnsafeJsEval.swift:211:24:211:37 | .utf8 | +| UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() | UnsafeJsEval.swift:217:35:217:35 | remoteString | | UnsafeJsEval.swift:204:7:204:66 | try! ... | UnsafeJsEval.swift:265:13:265:13 | string | | UnsafeJsEval.swift:204:7:204:66 | try! ... | UnsafeJsEval.swift:268:13:268:13 | string | | UnsafeJsEval.swift:204:7:204:66 | try! ... | UnsafeJsEval.swift:276:13:276:13 | string | @@ -32,6 +33,16 @@ edges | UnsafeJsEval.swift:214:7:214:49 | call to String.init(decoding:as:) | UnsafeJsEval.swift:285:13:285:13 | string | | UnsafeJsEval.swift:214:7:214:49 | call to String.init(decoding:as:) | UnsafeJsEval.swift:299:13:299:13 | string | | UnsafeJsEval.swift:214:24:214:24 | remoteData | UnsafeJsEval.swift:214:7:214:49 | call to String.init(decoding:as:) | +| UnsafeJsEval.swift:217:7:217:57 | ... .+(_:_:) ... | UnsafeJsEval.swift:265:13:265:13 | string | +| UnsafeJsEval.swift:217:7:217:57 | ... .+(_:_:) ... | UnsafeJsEval.swift:268:13:268:13 | string | +| UnsafeJsEval.swift:217:7:217:57 | ... .+(_:_:) ... | UnsafeJsEval.swift:276:13:276:13 | string | +| UnsafeJsEval.swift:217:7:217:57 | ... .+(_:_:) ... | UnsafeJsEval.swift:279:13:279:13 | string | +| UnsafeJsEval.swift:217:7:217:57 | ... .+(_:_:) ... | UnsafeJsEval.swift:285:13:285:13 | string | +| UnsafeJsEval.swift:217:7:217:57 | ... .+(_:_:) ... | UnsafeJsEval.swift:299:13:299:13 | string | +| UnsafeJsEval.swift:217:24:217:53 | call to String.init(_:) | UnsafeJsEval.swift:217:7:217:57 | ... .+(_:_:) ... | +| UnsafeJsEval.swift:217:31:217:47 | call to Self.init(_:) | UnsafeJsEval.swift:217:31:217:52 | ... ??(_:_:) ... | +| UnsafeJsEval.swift:217:31:217:52 | ... ??(_:_:) ... | UnsafeJsEval.swift:217:24:217:53 | call to String.init(_:) | +| UnsafeJsEval.swift:217:35:217:35 | remoteString | UnsafeJsEval.swift:217:31:217:47 | call to Self.init(_:) | | UnsafeJsEval.swift:265:13:265:13 | string | UnsafeJsEval.swift:266:43:266:43 | string | | UnsafeJsEval.swift:266:43:266:43 | string | UnsafeJsEval.swift:266:22:266:107 | call to WKUserScript.init(source:injectionTime:forMainFrameOnly:) | | UnsafeJsEval.swift:268:13:268:13 | string | UnsafeJsEval.swift:269:43:269:43 | string | @@ -67,6 +78,11 @@ nodes | UnsafeJsEval.swift:211:24:211:37 | .utf8 | semmle.label | .utf8 | | UnsafeJsEval.swift:214:7:214:49 | call to String.init(decoding:as:) | semmle.label | call to String.init(decoding:as:) | | UnsafeJsEval.swift:214:24:214:24 | remoteData | semmle.label | remoteData | +| UnsafeJsEval.swift:217:7:217:57 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... | +| UnsafeJsEval.swift:217:24:217:53 | call to String.init(_:) | semmle.label | call to String.init(_:) | +| UnsafeJsEval.swift:217:31:217:47 | call to Self.init(_:) | semmle.label | call to Self.init(_:) | +| UnsafeJsEval.swift:217:31:217:52 | ... ??(_:_:) ... | semmle.label | ... ??(_:_:) ... | +| UnsafeJsEval.swift:217:35:217:35 | remoteString | semmle.label | remoteString | | UnsafeJsEval.swift:265:13:265:13 | string | semmle.label | string | | UnsafeJsEval.swift:266:22:266:107 | call to WKUserScript.init(source:injectionTime:forMainFrameOnly:) | semmle.label | call to WKUserScript.init(source:injectionTime:forMainFrameOnly:) | | UnsafeJsEval.swift:266:43:266:43 | string | semmle.label | string | diff --git a/swift/ql/test/query-tests/Security/CWE-134/UncontrolledFormatString.expected b/swift/ql/test/query-tests/Security/CWE-134/UncontrolledFormatString.expected index 3a2d4eb80c6a..016c07cc2520 100644 --- a/swift/ql/test/query-tests/Security/CWE-134/UncontrolledFormatString.expected +++ b/swift/ql/test/query-tests/Security/CWE-134/UncontrolledFormatString.expected @@ -12,10 +12,18 @@ edges | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:85:72:85:72 | tainted | | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:88:11:88:11 | tainted | | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:91:61:91:61 | tainted | +| UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:93:26:93:26 | tainted | +| UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:97:27:97:27 | tainted | | UncontrolledFormatString.swift:81:47:81:47 | tainted | UncontrolledFormatString.swift:81:30:81:54 | call to NSString.init(string:) | | UncontrolledFormatString.swift:82:65:82:65 | tainted | UncontrolledFormatString.swift:82:48:82:72 | call to NSString.init(string:) | | UncontrolledFormatString.swift:84:54:84:54 | tainted | UncontrolledFormatString.swift:84:37:84:61 | call to NSString.init(string:) | | UncontrolledFormatString.swift:85:72:85:72 | tainted | UncontrolledFormatString.swift:85:55:85:79 | call to NSString.init(string:) | +| UncontrolledFormatString.swift:93:22:93:33 | call to Self.init(_:) | UncontrolledFormatString.swift:95:28:95:28 | taintedSan | +| UncontrolledFormatString.swift:93:26:93:26 | tainted | UncontrolledFormatString.swift:93:22:93:33 | call to Self.init(_:) | +| UncontrolledFormatString.swift:97:23:97:34 | call to Self.init(_:) | UncontrolledFormatString.swift:98:30:98:30 | taintedVal2 | +| UncontrolledFormatString.swift:97:27:97:27 | tainted | UncontrolledFormatString.swift:97:23:97:34 | call to Self.init(_:) | +| UncontrolledFormatString.swift:98:23:98:41 | call to String.init(_:) | UncontrolledFormatString.swift:99:28:99:28 | taintedSan2 | +| UncontrolledFormatString.swift:98:30:98:30 | taintedVal2 | UncontrolledFormatString.swift:98:23:98:41 | call to String.init(_:) | nodes | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | semmle.label | call to String.init(contentsOf:) | | UncontrolledFormatString.swift:70:28:70:28 | tainted | semmle.label | tainted | @@ -35,6 +43,14 @@ nodes | UncontrolledFormatString.swift:85:72:85:72 | tainted | semmle.label | tainted | | UncontrolledFormatString.swift:88:11:88:11 | tainted | semmle.label | tainted | | UncontrolledFormatString.swift:91:61:91:61 | tainted | semmle.label | tainted | +| UncontrolledFormatString.swift:93:22:93:33 | call to Self.init(_:) | semmle.label | call to Self.init(_:) | +| UncontrolledFormatString.swift:93:26:93:26 | tainted | semmle.label | tainted | +| UncontrolledFormatString.swift:95:28:95:28 | taintedSan | semmle.label | taintedSan | +| UncontrolledFormatString.swift:97:23:97:34 | call to Self.init(_:) | semmle.label | call to Self.init(_:) | +| UncontrolledFormatString.swift:97:27:97:27 | tainted | semmle.label | tainted | +| UncontrolledFormatString.swift:98:23:98:41 | call to String.init(_:) | semmle.label | call to String.init(_:) | +| UncontrolledFormatString.swift:98:30:98:30 | taintedVal2 | semmle.label | taintedVal2 | +| UncontrolledFormatString.swift:99:28:99:28 | taintedSan2 | semmle.label | taintedSan2 | subpaths #select | UncontrolledFormatString.swift:70:28:70:28 | tainted | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:70:28:70:28 | tainted | This format string depends on $@. | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | this user-provided value | @@ -50,3 +66,5 @@ subpaths | UncontrolledFormatString.swift:85:55:85:79 | call to NSString.init(string:) | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:85:55:85:79 | call to NSString.init(string:) | This format string depends on $@. | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | this user-provided value | | UncontrolledFormatString.swift:88:11:88:11 | tainted | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:88:11:88:11 | tainted | This format string depends on $@. | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | this user-provided value | | UncontrolledFormatString.swift:91:61:91:61 | tainted | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:91:61:91:61 | tainted | This format string depends on $@. | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | this user-provided value | +| UncontrolledFormatString.swift:95:28:95:28 | taintedSan | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:95:28:95:28 | taintedSan | This format string depends on $@. | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | this user-provided value | +| UncontrolledFormatString.swift:99:28:99:28 | taintedSan2 | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:99:28:99:28 | taintedSan2 | This format string depends on $@. | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | this user-provided value | diff --git a/swift/ql/test/query-tests/Security/CWE-134/UncontrolledFormatString.swift b/swift/ql/test/query-tests/Security/CWE-134/UncontrolledFormatString.swift index e5665eedeac7..d534ca552e35 100644 --- a/swift/ql/test/query-tests/Security/CWE-134/UncontrolledFormatString.swift +++ b/swift/ql/test/query-tests/Security/CWE-134/UncontrolledFormatString.swift @@ -92,9 +92,9 @@ func tests() { let taintedVal = Int(tainted)! let taintedSan = "\(taintedVal)" - let q = String(format: taintedSan) // GOOD: sufficiently sanitized + let q = String(format: taintedSan) // GOOD: sufficiently sanitized [FALSE POSITIVE] let taintedVal2 = Int(tainted) ?? 0 let taintedSan2 = String(taintedVal2) - let r = String(format: taintedSan2) // GOOD: sufficiently sanitized + let r = String(format: taintedSan2) // GOOD: sufficiently sanitized [FALSE POSITIVE] } From ee9a5c751c80183bff417999fbeaf52f09021f31 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 19 Sep 2023 13:21:27 +0100 Subject: [PATCH 14/20] Swift: Add numeric barrier for to the JS eval query. --- .../swift/security/UnsafeJsEvalExtensions.qll | 22 ++++++++++++++----- .../Security/CWE-094/UnsafeJsEval.expected | 16 -------------- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/swift/ql/lib/codeql/swift/security/UnsafeJsEvalExtensions.qll b/swift/ql/lib/codeql/swift/security/UnsafeJsEvalExtensions.qll index b1c353aff3c8..3eb65e6460f4 100644 --- a/swift/ql/lib/codeql/swift/security/UnsafeJsEvalExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/UnsafeJsEvalExtensions.qll @@ -30,7 +30,7 @@ class UnsafeJsEvalAdditionalFlowStep extends Unit { } /** - * A default SQL injection sink for the `WKWebView` interface. + * A default javascript evaluation sink for the `WKWebView` interface. */ private class WKWebViewDefaultUnsafeJsEvalSink extends UnsafeJsEvalSink { WKWebViewDefaultUnsafeJsEvalSink() { @@ -50,7 +50,7 @@ private class WKWebViewDefaultUnsafeJsEvalSink extends UnsafeJsEvalSink { } /** - * A default SQL injection sink for the `WKUserContentController` interface. + * A default javascript evaluation sink for the `WKUserContentController` interface. */ private class WKUserContentControllerDefaultUnsafeJsEvalSink extends UnsafeJsEvalSink { WKUserContentControllerDefaultUnsafeJsEvalSink() { @@ -61,7 +61,7 @@ private class WKUserContentControllerDefaultUnsafeJsEvalSink extends UnsafeJsEva } /** - * A default SQL injection sink for the `UIWebView` and `WebView` interfaces. + * A default javascript evaluation sink for the `UIWebView` and `WebView` interfaces. */ private class UIWebViewDefaultUnsafeJsEvalSink extends UnsafeJsEvalSink { UIWebViewDefaultUnsafeJsEvalSink() { @@ -74,7 +74,7 @@ private class UIWebViewDefaultUnsafeJsEvalSink extends UnsafeJsEvalSink { } /** - * A default SQL injection sink for the `JSContext` interface. + * A default javascript evaluation sink for the `JSContext` interface. */ private class JSContextDefaultUnsafeJsEvalSink extends UnsafeJsEvalSink { JSContextDefaultUnsafeJsEvalSink() { @@ -87,7 +87,7 @@ private class JSContextDefaultUnsafeJsEvalSink extends UnsafeJsEvalSink { } /** - * A default SQL injection sink for the `JSEvaluateScript` function. + * A default javascript evaluation sink for the `JSEvaluateScript` function. */ private class JSEvaluateScriptDefaultUnsafeJsEvalSink extends UnsafeJsEvalSink { JSEvaluateScriptDefaultUnsafeJsEvalSink() { @@ -98,7 +98,7 @@ private class JSEvaluateScriptDefaultUnsafeJsEvalSink extends UnsafeJsEvalSink { } /** - * A default SQL injection additional taint step. + * A default javascript evaluation additional taint step. */ private class DefaultUnsafeJsEvalAdditionalFlowStep extends UnsafeJsEvalAdditionalFlowStep { override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { @@ -120,3 +120,13 @@ private class DefaultUnsafeJsEvalAdditionalFlowStep extends UnsafeJsEvalAddition private class DefaultUnsafeJsEvalSink extends UnsafeJsEvalSink { DefaultUnsafeJsEvalSink() { sinkNode(this, "code-injection") } } + +/** + * A barrier for javascript evaluation. + */ +private class UnsafeJsEvalDefaultBarrier extends UnsafeJsEvalBarrier { + UnsafeJsEvalDefaultBarrier() { + // any numeric type + this.asExpr().getType().getUnderlyingType().getABaseType*().getName() = "Numeric" + } +} diff --git a/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected b/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected index fa14ba0ccdd8..da56e96c094a 100644 --- a/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected +++ b/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected @@ -4,7 +4,6 @@ edges | UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() | UnsafeJsEval.swift:205:7:205:7 | remoteString | | UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() | UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... | | UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() | UnsafeJsEval.swift:211:24:211:37 | .utf8 | -| UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() | UnsafeJsEval.swift:217:35:217:35 | remoteString | | UnsafeJsEval.swift:204:7:204:66 | try! ... | UnsafeJsEval.swift:265:13:265:13 | string | | UnsafeJsEval.swift:204:7:204:66 | try! ... | UnsafeJsEval.swift:268:13:268:13 | string | | UnsafeJsEval.swift:204:7:204:66 | try! ... | UnsafeJsEval.swift:276:13:276:13 | string | @@ -33,16 +32,6 @@ edges | UnsafeJsEval.swift:214:7:214:49 | call to String.init(decoding:as:) | UnsafeJsEval.swift:285:13:285:13 | string | | UnsafeJsEval.swift:214:7:214:49 | call to String.init(decoding:as:) | UnsafeJsEval.swift:299:13:299:13 | string | | UnsafeJsEval.swift:214:24:214:24 | remoteData | UnsafeJsEval.swift:214:7:214:49 | call to String.init(decoding:as:) | -| UnsafeJsEval.swift:217:7:217:57 | ... .+(_:_:) ... | UnsafeJsEval.swift:265:13:265:13 | string | -| UnsafeJsEval.swift:217:7:217:57 | ... .+(_:_:) ... | UnsafeJsEval.swift:268:13:268:13 | string | -| UnsafeJsEval.swift:217:7:217:57 | ... .+(_:_:) ... | UnsafeJsEval.swift:276:13:276:13 | string | -| UnsafeJsEval.swift:217:7:217:57 | ... .+(_:_:) ... | UnsafeJsEval.swift:279:13:279:13 | string | -| UnsafeJsEval.swift:217:7:217:57 | ... .+(_:_:) ... | UnsafeJsEval.swift:285:13:285:13 | string | -| UnsafeJsEval.swift:217:7:217:57 | ... .+(_:_:) ... | UnsafeJsEval.swift:299:13:299:13 | string | -| UnsafeJsEval.swift:217:24:217:53 | call to String.init(_:) | UnsafeJsEval.swift:217:7:217:57 | ... .+(_:_:) ... | -| UnsafeJsEval.swift:217:31:217:47 | call to Self.init(_:) | UnsafeJsEval.swift:217:31:217:52 | ... ??(_:_:) ... | -| UnsafeJsEval.swift:217:31:217:52 | ... ??(_:_:) ... | UnsafeJsEval.swift:217:24:217:53 | call to String.init(_:) | -| UnsafeJsEval.swift:217:35:217:35 | remoteString | UnsafeJsEval.swift:217:31:217:47 | call to Self.init(_:) | | UnsafeJsEval.swift:265:13:265:13 | string | UnsafeJsEval.swift:266:43:266:43 | string | | UnsafeJsEval.swift:266:43:266:43 | string | UnsafeJsEval.swift:266:22:266:107 | call to WKUserScript.init(source:injectionTime:forMainFrameOnly:) | | UnsafeJsEval.swift:268:13:268:13 | string | UnsafeJsEval.swift:269:43:269:43 | string | @@ -78,11 +67,6 @@ nodes | UnsafeJsEval.swift:211:24:211:37 | .utf8 | semmle.label | .utf8 | | UnsafeJsEval.swift:214:7:214:49 | call to String.init(decoding:as:) | semmle.label | call to String.init(decoding:as:) | | UnsafeJsEval.swift:214:24:214:24 | remoteData | semmle.label | remoteData | -| UnsafeJsEval.swift:217:7:217:57 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... | -| UnsafeJsEval.swift:217:24:217:53 | call to String.init(_:) | semmle.label | call to String.init(_:) | -| UnsafeJsEval.swift:217:31:217:47 | call to Self.init(_:) | semmle.label | call to Self.init(_:) | -| UnsafeJsEval.swift:217:31:217:52 | ... ??(_:_:) ... | semmle.label | ... ??(_:_:) ... | -| UnsafeJsEval.swift:217:35:217:35 | remoteString | semmle.label | remoteString | | UnsafeJsEval.swift:265:13:265:13 | string | semmle.label | string | | UnsafeJsEval.swift:266:22:266:107 | call to WKUserScript.init(source:injectionTime:forMainFrameOnly:) | semmle.label | call to WKUserScript.init(source:injectionTime:forMainFrameOnly:) | | UnsafeJsEval.swift:266:43:266:43 | string | semmle.label | string | From 903b0f5bab5b6dbf30eb87c9573af3770d0fbc54 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 19 Sep 2023 13:31:48 +0100 Subject: [PATCH 15/20] Swift: Add numeric barrier for the SQL Injinjection query. --- .../swift/security/SqlInjectionExtensions.qll | 10 ++++++++++ .../test/query-tests/Security/CWE-089/SQLite.swift | 2 +- .../Security/CWE-089/SqlInjection.expected | 14 -------------- .../Security/CWE-089/sqlite3_c_api.swift | 2 +- 4 files changed, 12 insertions(+), 16 deletions(-) diff --git a/swift/ql/lib/codeql/swift/security/SqlInjectionExtensions.qll b/swift/ql/lib/codeql/swift/security/SqlInjectionExtensions.qll index 1aac3571f538..48b2cadb3a8f 100644 --- a/swift/ql/lib/codeql/swift/security/SqlInjectionExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/SqlInjectionExtensions.qll @@ -153,3 +153,13 @@ private class GrdbDefaultSqlInjectionSink extends SqlInjectionSink { private class DefaultSqlInjectionSink extends SqlInjectionSink { DefaultSqlInjectionSink() { sinkNode(this, "sql-injection") } } + +/** + * A barrier for SQL injection. + */ +private class SqlInjectionDefaultBarrier extends SqlInjectionBarrier { + SqlInjectionDefaultBarrier() { + // any numeric type + this.asExpr().getType().getUnderlyingType().getABaseType*().getName() = "Numeric" + } +} diff --git a/swift/ql/test/query-tests/Security/CWE-089/SQLite.swift b/swift/ql/test/query-tests/Security/CWE-089/SQLite.swift index 7746c02a9d56..f9a6b41340ce 100644 --- a/swift/ql/test/query-tests/Security/CWE-089/SQLite.swift +++ b/swift/ql/test/query-tests/Security/CWE-089/SQLite.swift @@ -74,7 +74,7 @@ func test_sqlite_swift_api(db: Connection) throws { try db.execute(unsafeQuery2) // BAD try db.execute(unsafeQuery3) // BAD try db.execute(safeQuery1) // GOOD - try db.execute(safeQuery2) // GOOD [FALSE POSITIVE] + try db.execute(safeQuery2) // GOOD // --- prepared statements --- diff --git a/swift/ql/test/query-tests/Security/CWE-089/SqlInjection.expected b/swift/ql/test/query-tests/Security/CWE-089/SqlInjection.expected index 65b3383cdef5..a4617e9b8114 100644 --- a/swift/ql/test/query-tests/Security/CWE-089/SqlInjection.expected +++ b/swift/ql/test/query-tests/Security/CWE-089/SqlInjection.expected @@ -82,7 +82,6 @@ edges | GRDB.swift:342:26:342:80 | call to String.init(contentsOf:) | GRDB.swift:349:84:349:84 | remoteString | | GRDB.swift:342:26:342:80 | call to String.init(contentsOf:) | GRDB.swift:350:69:350:69 | remoteString | | GRDB.swift:342:26:342:80 | call to String.init(contentsOf:) | GRDB.swift:351:84:351:84 | remoteString | -| SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:63:25:63:25 | remoteString | | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:73:17:73:17 | unsafeQuery1 | | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:74:17:74:17 | unsafeQuery2 | | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:75:17:75:17 | unsafeQuery3 | @@ -98,9 +97,6 @@ edges | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:117:16:117:16 | unsafeQuery1 | | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:119:16:119:16 | unsafeQuery1 | | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:132:20:132:20 | remoteString | -| SQLite.swift:63:21:63:37 | call to Self.init(_:) | SQLite.swift:77:17:77:17 | safeQuery2 | -| SQLite.swift:63:25:63:25 | remoteString | SQLite.swift:63:21:63:37 | call to Self.init(_:) | -| sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:123:25:123:25 | remoteString | | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:133:33:133:33 | unsafeQuery1 | | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:134:33:134:33 | unsafeQuery2 | | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:135:33:135:33 | unsafeQuery3 | @@ -108,8 +104,6 @@ edges | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:175:29:175:29 | unsafeQuery3 | | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:183:29:183:29 | unsafeQuery3 | | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:189:13:189:13 | unsafeQuery3 | -| sqlite3_c_api.swift:123:21:123:37 | call to Self.init(_:) | sqlite3_c_api.swift:137:33:137:33 | safeQuery2 | -| sqlite3_c_api.swift:123:25:123:25 | remoteString | sqlite3_c_api.swift:123:21:123:37 | call to Self.init(_:) | | sqlite3_c_api.swift:189:13:189:13 | unsafeQuery3 | sqlite3_c_api.swift:189:13:189:58 | call to data(using:allowLossyConversion:) | | sqlite3_c_api.swift:189:13:189:58 | call to data(using:allowLossyConversion:) | sqlite3_c_api.swift:190:2:190:2 | data | | sqlite3_c_api.swift:190:2:190:2 | data | sqlite3_c_api.swift:190:21:190:21 | [post] buffer | @@ -213,12 +207,9 @@ nodes | GRDB.swift:350:69:350:69 | remoteString | semmle.label | remoteString | | GRDB.swift:351:84:351:84 | remoteString | semmle.label | remoteString | | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | semmle.label | call to String.init(contentsOf:) | -| SQLite.swift:63:21:63:37 | call to Self.init(_:) | semmle.label | call to Self.init(_:) | -| SQLite.swift:63:25:63:25 | remoteString | semmle.label | remoteString | | SQLite.swift:73:17:73:17 | unsafeQuery1 | semmle.label | unsafeQuery1 | | SQLite.swift:74:17:74:17 | unsafeQuery2 | semmle.label | unsafeQuery2 | | SQLite.swift:75:17:75:17 | unsafeQuery3 | semmle.label | unsafeQuery3 | -| SQLite.swift:77:17:77:17 | safeQuery2 | semmle.label | safeQuery2 | | SQLite.swift:83:29:83:29 | unsafeQuery3 | semmle.label | unsafeQuery3 | | SQLite.swift:95:32:95:32 | remoteString | semmle.label | remoteString | | SQLite.swift:100:29:100:29 | unsafeQuery1 | semmle.label | unsafeQuery1 | @@ -232,12 +223,9 @@ nodes | SQLite.swift:119:16:119:16 | unsafeQuery1 | semmle.label | unsafeQuery1 | | SQLite.swift:132:20:132:20 | remoteString | semmle.label | remoteString | | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | semmle.label | call to String.init(contentsOf:) | -| sqlite3_c_api.swift:123:21:123:37 | call to Self.init(_:) | semmle.label | call to Self.init(_:) | -| sqlite3_c_api.swift:123:25:123:25 | remoteString | semmle.label | remoteString | | sqlite3_c_api.swift:133:33:133:33 | unsafeQuery1 | semmle.label | unsafeQuery1 | | sqlite3_c_api.swift:134:33:134:33 | unsafeQuery2 | semmle.label | unsafeQuery2 | | sqlite3_c_api.swift:135:33:135:33 | unsafeQuery3 | semmle.label | unsafeQuery3 | -| sqlite3_c_api.swift:137:33:137:33 | safeQuery2 | semmle.label | safeQuery2 | | sqlite3_c_api.swift:145:26:145:26 | unsafeQuery3 | semmle.label | unsafeQuery3 | | sqlite3_c_api.swift:175:29:175:29 | unsafeQuery3 | semmle.label | unsafeQuery3 | | sqlite3_c_api.swift:183:29:183:29 | unsafeQuery3 | semmle.label | unsafeQuery3 | @@ -336,7 +324,6 @@ subpaths | SQLite.swift:73:17:73:17 | unsafeQuery1 | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:73:17:73:17 | unsafeQuery1 | This query depends on a $@. | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | user-provided value | | SQLite.swift:74:17:74:17 | unsafeQuery2 | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:74:17:74:17 | unsafeQuery2 | This query depends on a $@. | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | user-provided value | | SQLite.swift:75:17:75:17 | unsafeQuery3 | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:75:17:75:17 | unsafeQuery3 | This query depends on a $@. | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | user-provided value | -| SQLite.swift:77:17:77:17 | safeQuery2 | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:77:17:77:17 | safeQuery2 | This query depends on a $@. | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | user-provided value | | SQLite.swift:83:29:83:29 | unsafeQuery3 | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:83:29:83:29 | unsafeQuery3 | This query depends on a $@. | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | user-provided value | | SQLite.swift:95:32:95:32 | remoteString | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:95:32:95:32 | remoteString | This query depends on a $@. | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | user-provided value | | SQLite.swift:100:29:100:29 | unsafeQuery1 | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:100:29:100:29 | unsafeQuery1 | This query depends on a $@. | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | user-provided value | @@ -352,7 +339,6 @@ subpaths | sqlite3_c_api.swift:133:33:133:33 | unsafeQuery1 | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:133:33:133:33 | unsafeQuery1 | This query depends on a $@. | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | user-provided value | | sqlite3_c_api.swift:134:33:134:33 | unsafeQuery2 | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:134:33:134:33 | unsafeQuery2 | This query depends on a $@. | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | user-provided value | | sqlite3_c_api.swift:135:33:135:33 | unsafeQuery3 | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:135:33:135:33 | unsafeQuery3 | This query depends on a $@. | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | user-provided value | -| sqlite3_c_api.swift:137:33:137:33 | safeQuery2 | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:137:33:137:33 | safeQuery2 | This query depends on a $@. | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | user-provided value | | sqlite3_c_api.swift:145:26:145:26 | unsafeQuery3 | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:145:26:145:26 | unsafeQuery3 | This query depends on a $@. | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | user-provided value | | sqlite3_c_api.swift:175:29:175:29 | unsafeQuery3 | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:175:29:175:29 | unsafeQuery3 | This query depends on a $@. | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | user-provided value | | sqlite3_c_api.swift:183:29:183:29 | unsafeQuery3 | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:183:29:183:29 | unsafeQuery3 | This query depends on a $@. | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | user-provided value | diff --git a/swift/ql/test/query-tests/Security/CWE-089/sqlite3_c_api.swift b/swift/ql/test/query-tests/Security/CWE-089/sqlite3_c_api.swift index 06846cd2072f..8498d89d68da 100644 --- a/swift/ql/test/query-tests/Security/CWE-089/sqlite3_c_api.swift +++ b/swift/ql/test/query-tests/Security/CWE-089/sqlite3_c_api.swift @@ -134,7 +134,7 @@ func test_sqlite3_c_api(db: OpaquePointer?, buffer: UnsafeMutablePointer) let result2 = sqlite3_exec(db, unsafeQuery2, nil, nil, nil) // BAD let result3 = sqlite3_exec(db, unsafeQuery3, nil, nil, nil) // BAD let result4 = sqlite3_exec(db, safeQuery1, nil, nil, nil) // GOOD - let result5 = sqlite3_exec(db, safeQuery2, nil, nil, nil) // GOOD [FALSE POSITIVE] + let result5 = sqlite3_exec(db, safeQuery2, nil, nil, nil) // GOOD // --- prepared statements --- From f98de85e36b0542dc99cc547b2157a97d46dcf78 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 19 Sep 2023 14:09:22 +0100 Subject: [PATCH 16/20] Swift: Add numeric barrier for command injection query. --- .../swift/security/CommandInjectionExtensions.qll | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/swift/ql/lib/codeql/swift/security/CommandInjectionExtensions.qll b/swift/ql/lib/codeql/swift/security/CommandInjectionExtensions.qll index 5b1cc065ec28..5d78e82e76d6 100644 --- a/swift/ql/lib/codeql/swift/security/CommandInjectionExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/CommandInjectionExtensions.qll @@ -69,3 +69,13 @@ private class CommandInjectionSinks extends SinkModelCsv { ] } } + +/** + * A barrier for command injection vulnerabilities. + */ +private class CommandInjectionDefaultBarrier extends CommandInjectionBarrier { + CommandInjectionDefaultBarrier() { + // any numeric type + this.asExpr().getType().getUnderlyingType().getABaseType*().getName() = "Numeric" + } +} From 2983295ba35225fc3261c65e12db70f63aa3f825 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 19 Sep 2023 14:19:12 +0100 Subject: [PATCH 17/20] Swift: Add numeric barrier for uncontrolled format string query. --- .../UncontrolledFormatStringExtensions.qll | 10 ++++++++++ .../CWE-134/UncontrolledFormatString.expected | 18 ------------------ .../CWE-134/UncontrolledFormatString.swift | 4 ++-- 3 files changed, 12 insertions(+), 20 deletions(-) diff --git a/swift/ql/lib/codeql/swift/security/UncontrolledFormatStringExtensions.qll b/swift/ql/lib/codeql/swift/security/UncontrolledFormatStringExtensions.qll index c2d587a35c24..835d4b1e65c3 100644 --- a/swift/ql/lib/codeql/swift/security/UncontrolledFormatStringExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/UncontrolledFormatStringExtensions.qll @@ -42,3 +42,13 @@ private class DefaultUncontrolledFormatStringSink extends UncontrolledFormatStri sinkNode(this, "format-string") } } + +/** + * A barrier for uncontrolled format string vulnerabilities. + */ +private class UncontrolledFormatStringDefaultBarrier extends UncontrolledFormatStringBarrier { + UncontrolledFormatStringDefaultBarrier() { + // any numeric type + this.asExpr().getType().getUnderlyingType().getABaseType*().getName() = "Numeric" + } +} diff --git a/swift/ql/test/query-tests/Security/CWE-134/UncontrolledFormatString.expected b/swift/ql/test/query-tests/Security/CWE-134/UncontrolledFormatString.expected index 016c07cc2520..3a2d4eb80c6a 100644 --- a/swift/ql/test/query-tests/Security/CWE-134/UncontrolledFormatString.expected +++ b/swift/ql/test/query-tests/Security/CWE-134/UncontrolledFormatString.expected @@ -12,18 +12,10 @@ edges | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:85:72:85:72 | tainted | | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:88:11:88:11 | tainted | | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:91:61:91:61 | tainted | -| UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:93:26:93:26 | tainted | -| UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:97:27:97:27 | tainted | | UncontrolledFormatString.swift:81:47:81:47 | tainted | UncontrolledFormatString.swift:81:30:81:54 | call to NSString.init(string:) | | UncontrolledFormatString.swift:82:65:82:65 | tainted | UncontrolledFormatString.swift:82:48:82:72 | call to NSString.init(string:) | | UncontrolledFormatString.swift:84:54:84:54 | tainted | UncontrolledFormatString.swift:84:37:84:61 | call to NSString.init(string:) | | UncontrolledFormatString.swift:85:72:85:72 | tainted | UncontrolledFormatString.swift:85:55:85:79 | call to NSString.init(string:) | -| UncontrolledFormatString.swift:93:22:93:33 | call to Self.init(_:) | UncontrolledFormatString.swift:95:28:95:28 | taintedSan | -| UncontrolledFormatString.swift:93:26:93:26 | tainted | UncontrolledFormatString.swift:93:22:93:33 | call to Self.init(_:) | -| UncontrolledFormatString.swift:97:23:97:34 | call to Self.init(_:) | UncontrolledFormatString.swift:98:30:98:30 | taintedVal2 | -| UncontrolledFormatString.swift:97:27:97:27 | tainted | UncontrolledFormatString.swift:97:23:97:34 | call to Self.init(_:) | -| UncontrolledFormatString.swift:98:23:98:41 | call to String.init(_:) | UncontrolledFormatString.swift:99:28:99:28 | taintedSan2 | -| UncontrolledFormatString.swift:98:30:98:30 | taintedVal2 | UncontrolledFormatString.swift:98:23:98:41 | call to String.init(_:) | nodes | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | semmle.label | call to String.init(contentsOf:) | | UncontrolledFormatString.swift:70:28:70:28 | tainted | semmle.label | tainted | @@ -43,14 +35,6 @@ nodes | UncontrolledFormatString.swift:85:72:85:72 | tainted | semmle.label | tainted | | UncontrolledFormatString.swift:88:11:88:11 | tainted | semmle.label | tainted | | UncontrolledFormatString.swift:91:61:91:61 | tainted | semmle.label | tainted | -| UncontrolledFormatString.swift:93:22:93:33 | call to Self.init(_:) | semmle.label | call to Self.init(_:) | -| UncontrolledFormatString.swift:93:26:93:26 | tainted | semmle.label | tainted | -| UncontrolledFormatString.swift:95:28:95:28 | taintedSan | semmle.label | taintedSan | -| UncontrolledFormatString.swift:97:23:97:34 | call to Self.init(_:) | semmle.label | call to Self.init(_:) | -| UncontrolledFormatString.swift:97:27:97:27 | tainted | semmle.label | tainted | -| UncontrolledFormatString.swift:98:23:98:41 | call to String.init(_:) | semmle.label | call to String.init(_:) | -| UncontrolledFormatString.swift:98:30:98:30 | taintedVal2 | semmle.label | taintedVal2 | -| UncontrolledFormatString.swift:99:28:99:28 | taintedSan2 | semmle.label | taintedSan2 | subpaths #select | UncontrolledFormatString.swift:70:28:70:28 | tainted | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:70:28:70:28 | tainted | This format string depends on $@. | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | this user-provided value | @@ -66,5 +50,3 @@ subpaths | UncontrolledFormatString.swift:85:55:85:79 | call to NSString.init(string:) | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:85:55:85:79 | call to NSString.init(string:) | This format string depends on $@. | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | this user-provided value | | UncontrolledFormatString.swift:88:11:88:11 | tainted | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:88:11:88:11 | tainted | This format string depends on $@. | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | this user-provided value | | UncontrolledFormatString.swift:91:61:91:61 | tainted | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:91:61:91:61 | tainted | This format string depends on $@. | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | this user-provided value | -| UncontrolledFormatString.swift:95:28:95:28 | taintedSan | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:95:28:95:28 | taintedSan | This format string depends on $@. | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | this user-provided value | -| UncontrolledFormatString.swift:99:28:99:28 | taintedSan2 | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:99:28:99:28 | taintedSan2 | This format string depends on $@. | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | this user-provided value | diff --git a/swift/ql/test/query-tests/Security/CWE-134/UncontrolledFormatString.swift b/swift/ql/test/query-tests/Security/CWE-134/UncontrolledFormatString.swift index d534ca552e35..e5665eedeac7 100644 --- a/swift/ql/test/query-tests/Security/CWE-134/UncontrolledFormatString.swift +++ b/swift/ql/test/query-tests/Security/CWE-134/UncontrolledFormatString.swift @@ -92,9 +92,9 @@ func tests() { let taintedVal = Int(tainted)! let taintedSan = "\(taintedVal)" - let q = String(format: taintedSan) // GOOD: sufficiently sanitized [FALSE POSITIVE] + let q = String(format: taintedSan) // GOOD: sufficiently sanitized let taintedVal2 = Int(tainted) ?? 0 let taintedSan2 = String(taintedVal2) - let r = String(format: taintedSan2) // GOOD: sufficiently sanitized [FALSE POSITIVE] + let r = String(format: taintedSan2) // GOOD: sufficiently sanitized } From 597554609827c6320bc78c6bb08216d0bd7eb3a5 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 19 Sep 2023 14:21:04 +0100 Subject: [PATCH 18/20] Swift: Add numeric barrier for predicate injection query as well. --- .../swift/security/PredicateInjectionExtensions.qll | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/swift/ql/lib/codeql/swift/security/PredicateInjectionExtensions.qll b/swift/ql/lib/codeql/swift/security/PredicateInjectionExtensions.qll index e703d1d21e83..9e5a8a8e57b8 100644 --- a/swift/ql/lib/codeql/swift/security/PredicateInjectionExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/PredicateInjectionExtensions.qll @@ -39,3 +39,13 @@ private class PredicateInjectionSinkCsv extends SinkModelCsv { ] } } + +/** + * A barrier for predicate injection vulnerabilities vulnerabilities. + */ +private class PredicateInjectionDefaultBarrier extends PredicateInjectionBarrier { + PredicateInjectionDefaultBarrier() { + // any numeric type + this.asExpr().getType().getUnderlyingType().getABaseType*().getName() = "Numeric" + } +} From e011951e1f11b17224bf1bf3586e8333ff8bb335 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 19 Sep 2023 14:58:29 +0100 Subject: [PATCH 19/20] Swift: Added change note for the new barriers. --- swift/ql/src/change-notes/2023-09-19-numeric-barriers.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 swift/ql/src/change-notes/2023-09-19-numeric-barriers.md diff --git a/swift/ql/src/change-notes/2023-09-19-numeric-barriers.md b/swift/ql/src/change-notes/2023-09-19-numeric-barriers.md new file mode 100644 index 000000000000..568ed104d66b --- /dev/null +++ b/swift/ql/src/change-notes/2023-09-19-numeric-barriers.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Adder barriers for numeric type values to the injection-like queries, to reduce false positive results where the user input that can be injected is constrainted to a numerical value. The queries updated by this change are: "Predicate built from user-controlled sources" (`swift/predicate-injection`), "Database query built from user-controlled sources" (`swift/sql-injection`), "Uncontrolled format string" (`swift/uncontrolled-format-string`) and "JavaScript Injection" (`swift/unsafe-js-eval`). From ae159924a3384457043caf2a74ff1c26bf440583 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 19 Sep 2023 15:04:33 +0100 Subject: [PATCH 20/20] Swift: Add numeric barrier to the regular expression injection query as well. --- .../swift/security/regex/RegexInjectionExtensions.qll | 10 ++++++++++ .../ql/src/change-notes/2023-09-19-numeric-barriers.md | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/swift/ql/lib/codeql/swift/security/regex/RegexInjectionExtensions.qll b/swift/ql/lib/codeql/swift/security/regex/RegexInjectionExtensions.qll index 3c6003b8bc80..75cf303ed620 100644 --- a/swift/ql/lib/codeql/swift/security/regex/RegexInjectionExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/regex/RegexInjectionExtensions.qll @@ -57,3 +57,13 @@ private class RegexInjectionSinks extends SinkModelCsv { ] } } + +/** + * A barrier for regular expression injection vulnerabilities. + */ +private class RegexInjectionDefaultBarrier extends RegexInjectionBarrier { + RegexInjectionDefaultBarrier() { + // any numeric type + this.asExpr().getType().getUnderlyingType().getABaseType*().getName() = "Numeric" + } +} diff --git a/swift/ql/src/change-notes/2023-09-19-numeric-barriers.md b/swift/ql/src/change-notes/2023-09-19-numeric-barriers.md index 568ed104d66b..0fd9989afe13 100644 --- a/swift/ql/src/change-notes/2023-09-19-numeric-barriers.md +++ b/swift/ql/src/change-notes/2023-09-19-numeric-barriers.md @@ -1,4 +1,4 @@ --- category: minorAnalysis --- -* Adder barriers for numeric type values to the injection-like queries, to reduce false positive results where the user input that can be injected is constrainted to a numerical value. The queries updated by this change are: "Predicate built from user-controlled sources" (`swift/predicate-injection`), "Database query built from user-controlled sources" (`swift/sql-injection`), "Uncontrolled format string" (`swift/uncontrolled-format-string`) and "JavaScript Injection" (`swift/unsafe-js-eval`). +* Adder barriers for numeric type values to the injection-like queries, to reduce false positive results where the user input that can be injected is constrainted to a numerical value. The queries updated by this change are: "Predicate built from user-controlled sources" (`swift/predicate-injection`), "Database query built from user-controlled sources" (`swift/sql-injection`), "Uncontrolled format string" (`swift/uncontrolled-format-string`), "JavaScript Injection" (`swift/unsafe-js-eval`) and "Regular expression injection" (`swift/regex-injection`).