-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10000 from geoffw0/defaulttaint
Swift: Taint flow improvements
- Loading branch information
Showing
11 changed files
with
479 additions
and
185 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
343 changes: 222 additions & 121 deletions
343
swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected
Large diffs are not rendered by default.
Oops, something went wrong.
73 changes: 57 additions & 16 deletions
73
swift/ql/test/library-tests/dataflow/taint/Taint.expected
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,61 @@ | ||
edges | ||
| test.swift:5:11:5:18 | call to source() : | test.swift:7:13:7:13 | "..." | | ||
| test.swift:5:11:5:18 | call to source() : | test.swift:9:13:9:13 | "..." | | ||
| test.swift:5:11:5:18 | call to source() : | test.swift:11:13:11:13 | "..." | | ||
| test.swift:5:11:5:18 | call to source() : | test.swift:16:13:16:13 | "..." | | ||
| test.swift:5:11:5:18 | call to source() : | test.swift:18:13:18:13 | "..." | | ||
| string.swift:5:11:5:18 | call to source() : | string.swift:7:13:7:13 | "..." | | ||
| string.swift:5:11:5:18 | call to source() : | string.swift:9:13:9:13 | "..." | | ||
| string.swift:5:11:5:18 | call to source() : | string.swift:11:13:11:13 | "..." | | ||
| string.swift:5:11:5:18 | call to source() : | string.swift:16:13:16:13 | "..." | | ||
| string.swift:5:11:5:18 | call to source() : | string.swift:18:13:18:13 | "..." | | ||
| string.swift:28:17:28:25 | call to source2() : | string.swift:31:13:31:13 | tainted | | ||
| string.swift:28:17:28:25 | call to source2() : | string.swift:34:13:34:21 | ... call to +(_:_:) ... | | ||
| string.swift:28:17:28:25 | call to source2() : | string.swift:35:13:35:23 | ... call to +(_:_:) ... | | ||
| string.swift:28:17:28:25 | call to source2() : | string.swift:36:13:36:23 | ... call to +(_:_:) ... | | ||
| string.swift:28:17:28:25 | call to source2() : | string.swift:39:13:39:29 | ... call to +(_:_:) ... | | ||
| try.swift:9:17:9:24 | call to source() : | try.swift:9:13:9:24 | try ... | | ||
| try.swift:15:17:15:24 | call to source() : | try.swift:15:12:15:24 | try! ... | | ||
| try.swift:18:18:18:25 | call to source() : | try.swift:18:12:18:27 | ...! | | ||
| url.swift:13:16:13:23 | call to source() : | url.swift:18:12:18:12 | urlTainted | | ||
| url.swift:13:16:13:23 | call to source() : | url.swift:21:12:21:49 | ...! | | ||
| url.swift:13:16:13:23 | call to source() : | url.swift:23:12:23:54 | ...! | | ||
| url.swift:13:16:13:23 | call to source() : | url.swift:39:12:39:12 | ...! | | ||
nodes | ||
| test.swift:5:11:5:18 | call to source() : | semmle.label | call to source() : | | ||
| test.swift:7:13:7:13 | "..." | semmle.label | "..." | | ||
| test.swift:9:13:9:13 | "..." | semmle.label | "..." | | ||
| test.swift:11:13:11:13 | "..." | semmle.label | "..." | | ||
| test.swift:16:13:16:13 | "..." | semmle.label | "..." | | ||
| test.swift:18:13:18:13 | "..." | semmle.label | "..." | | ||
| string.swift:5:11:5:18 | call to source() : | semmle.label | call to source() : | | ||
| string.swift:7:13:7:13 | "..." | semmle.label | "..." | | ||
| string.swift:9:13:9:13 | "..." | semmle.label | "..." | | ||
| string.swift:11:13:11:13 | "..." | semmle.label | "..." | | ||
| string.swift:16:13:16:13 | "..." | semmle.label | "..." | | ||
| string.swift:18:13:18:13 | "..." | semmle.label | "..." | | ||
| string.swift:28:17:28:25 | call to source2() : | semmle.label | call to source2() : | | ||
| string.swift:31:13:31:13 | tainted | semmle.label | tainted | | ||
| string.swift:34:13:34:21 | ... call to +(_:_:) ... | semmle.label | ... call to +(_:_:) ... | | ||
| string.swift:35:13:35:23 | ... call to +(_:_:) ... | semmle.label | ... call to +(_:_:) ... | | ||
| string.swift:36:13:36:23 | ... call to +(_:_:) ... | semmle.label | ... call to +(_:_:) ... | | ||
| string.swift:39:13:39:29 | ... call to +(_:_:) ... | semmle.label | ... call to +(_:_:) ... | | ||
| try.swift:9:13:9:24 | try ... | semmle.label | try ... | | ||
| try.swift:9:17:9:24 | call to source() : | semmle.label | call to source() : | | ||
| try.swift:15:12:15:24 | try! ... | semmle.label | try! ... | | ||
| try.swift:15:17:15:24 | call to source() : | semmle.label | call to source() : | | ||
| try.swift:18:12:18:27 | ...! | semmle.label | ...! | | ||
| try.swift:18:18:18:25 | call to source() : | semmle.label | call to source() : | | ||
| url.swift:13:16:13:23 | call to source() : | semmle.label | call to source() : | | ||
| url.swift:18:12:18:12 | urlTainted | semmle.label | urlTainted | | ||
| url.swift:21:12:21:49 | ...! | semmle.label | ...! | | ||
| url.swift:23:12:23:54 | ...! | semmle.label | ...! | | ||
| url.swift:39:12:39:12 | ...! | semmle.label | ...! | | ||
subpaths | ||
#select | ||
| test.swift:7:13:7:13 | "..." | test.swift:5:11:5:18 | call to source() : | test.swift:7:13:7:13 | "..." | result | | ||
| test.swift:9:13:9:13 | "..." | test.swift:5:11:5:18 | call to source() : | test.swift:9:13:9:13 | "..." | result | | ||
| test.swift:11:13:11:13 | "..." | test.swift:5:11:5:18 | call to source() : | test.swift:11:13:11:13 | "..." | result | | ||
| test.swift:16:13:16:13 | "..." | test.swift:5:11:5:18 | call to source() : | test.swift:16:13:16:13 | "..." | result | | ||
| test.swift:18:13:18:13 | "..." | test.swift:5:11:5:18 | call to source() : | test.swift:18:13:18:13 | "..." | result | | ||
| string.swift:7:13:7:13 | "..." | string.swift:5:11:5:18 | call to source() : | string.swift:7:13:7:13 | "..." | result | | ||
| string.swift:9:13:9:13 | "..." | string.swift:5:11:5:18 | call to source() : | string.swift:9:13:9:13 | "..." | result | | ||
| string.swift:11:13:11:13 | "..." | string.swift:5:11:5:18 | call to source() : | string.swift:11:13:11:13 | "..." | result | | ||
| string.swift:16:13:16:13 | "..." | string.swift:5:11:5:18 | call to source() : | string.swift:16:13:16:13 | "..." | result | | ||
| string.swift:18:13:18:13 | "..." | string.swift:5:11:5:18 | call to source() : | string.swift:18:13:18:13 | "..." | result | | ||
| string.swift:31:13:31:13 | tainted | string.swift:28:17:28:25 | call to source2() : | string.swift:31:13:31:13 | tainted | result | | ||
| string.swift:34:13:34:21 | ... call to +(_:_:) ... | string.swift:28:17:28:25 | call to source2() : | string.swift:34:13:34:21 | ... call to +(_:_:) ... | result | | ||
| string.swift:35:13:35:23 | ... call to +(_:_:) ... | string.swift:28:17:28:25 | call to source2() : | string.swift:35:13:35:23 | ... call to +(_:_:) ... | result | | ||
| string.swift:36:13:36:23 | ... call to +(_:_:) ... | string.swift:28:17:28:25 | call to source2() : | string.swift:36:13:36:23 | ... call to +(_:_:) ... | result | | ||
| string.swift:39:13:39:29 | ... call to +(_:_:) ... | string.swift:28:17:28:25 | call to source2() : | string.swift:39:13:39:29 | ... call to +(_:_:) ... | result | | ||
| try.swift:9:13:9:24 | try ... | try.swift:9:17:9:24 | call to source() : | try.swift:9:13:9:24 | try ... | result | | ||
| try.swift:15:12:15:24 | try! ... | try.swift:15:17:15:24 | call to source() : | try.swift:15:12:15:24 | try! ... | result | | ||
| try.swift:18:12:18:27 | ...! | try.swift:18:18:18:25 | call to source() : | try.swift:18:12:18:27 | ...! | result | | ||
| url.swift:18:12:18:12 | urlTainted | url.swift:13:16:13:23 | call to source() : | url.swift:18:12:18:12 | urlTainted | result | | ||
| url.swift:21:12:21:49 | ...! | url.swift:13:16:13:23 | call to source() : | url.swift:21:12:21:49 | ...! | result | | ||
| url.swift:23:12:23:54 | ...! | url.swift:13:16:13:23 | call to source() : | url.swift:23:12:23:54 | ...! | result | | ||
| url.swift:39:12:39:12 | ...! | url.swift:13:16:13:23 | call to source() : | url.swift:39:12:39:12 | ...! | result | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
|
||
class Data | ||
{ | ||
init<S>(_ elements: S) {} | ||
} | ||
|
||
func source() -> String { return "" } | ||
func sink(arg: Data) {} | ||
func sink2(arg: String) {} | ||
|
||
func taintThroughData() { | ||
let dataClean = Data("123456".utf8) | ||
let dataTainted = Data(source().utf8) | ||
let dataTainted2 = Data(dataTainted) | ||
|
||
sink(arg: dataClean) | ||
sink(arg: dataTainted) // tainted [NOT DETECTED] | ||
sink(arg: dataTainted2) // tainted [NOT DETECTED] | ||
|
||
let stringClean = String(data: dataClean, encoding: String.Encoding.utf8) | ||
let stringTainted = String(data: dataTainted, encoding: String.Encoding.utf8) | ||
|
||
sink2(arg: stringClean!) // tainted [NOT DETECTED] | ||
sink2(arg: stringTainted!) // tainted [NOT DETECTED] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
func source() -> Int { return 0; } | ||
func sink(arg: String) {} | ||
|
||
func taintThroughInterpolatedStrings() { | ||
var x = source() | ||
|
||
sink(arg: "\(x)") // tainted | ||
|
||
sink(arg: "\(x) \(x)") // tainted | ||
|
||
sink(arg: "\(x) \(0) \(x)") // tainted | ||
|
||
var y = 42 | ||
sink(arg: "\(y)") // clean | ||
|
||
sink(arg: "\(x) hello \(y)") // tainted | ||
|
||
sink(arg: "\(y) world \(x)") // tainted | ||
|
||
x = 0 | ||
sink(arg: "\(x)") // clean | ||
} | ||
|
||
func source2() -> String { return ""; } | ||
|
||
func taintThroughStringConcatenation() { | ||
var clean = "abcdef" | ||
var tainted = source2() | ||
|
||
sink(arg: clean) | ||
sink(arg: tainted) // tainted | ||
|
||
sink(arg: clean + clean) | ||
sink(arg: clean + tainted) // tainted | ||
sink(arg: tainted + clean) // tainted | ||
sink(arg: tainted + tainted) // tainted | ||
|
||
sink(arg: ">" + clean + "<") | ||
sink(arg: ">" + tainted + "<") // tainted | ||
|
||
var str = "abc" | ||
|
||
sink(arg: str) | ||
|
||
str += "def" | ||
sink(arg: str) | ||
|
||
str += source2() | ||
sink(arg: str) // tainted [NOT DETECTED] | ||
|
||
var str2 = "abc" | ||
|
||
sink(arg: str2) | ||
|
||
str2.append("def") | ||
sink(arg: str2) | ||
|
||
str2.append(source2()) | ||
sink(arg: str2) // tainted [NOT DETECTED] | ||
|
||
var str3 = "abc" | ||
|
||
sink(arg: str3) | ||
|
||
str3.append(contentsOf: "def") | ||
sink(arg: str3) | ||
|
||
str3.append(contentsOf: source2()) | ||
sink(arg: str2) // tainted [NOT DETECTED] | ||
} | ||
|
||
func taintThroughStringOperations() { | ||
var clean = "" | ||
var tainted = source2() | ||
var taintedInt = source() | ||
|
||
sink(arg: String(clean)) | ||
sink(arg: String(tainted)) // tainted [NOT DETECTED] | ||
sink(arg: String(taintedInt)) // tainted [NOT DETECTED] | ||
|
||
sink(arg: String(repeating: clean, count: 2)) | ||
sink(arg: String(repeating: tainted, count: 2)) // tainted [NOT DETECTED] | ||
|
||
sink(arg: clean.description) | ||
sink(arg: tainted.description) // tainted [NOT DETECTED] | ||
|
||
sink(arg: clean.debugDescription) | ||
sink(arg: tainted.debugDescription) // tainted [NOT DETECTED] | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
func clean() throws -> String { return ""; } | ||
func source() throws -> String { return ""; } | ||
func sink(arg: String) {} | ||
|
||
func taintThroughTry() { | ||
do | ||
{ | ||
sink(arg: try clean()) | ||
sink(arg: try source()) // tainted | ||
} catch { | ||
// ... | ||
} | ||
|
||
sink(arg: try! clean()) | ||
sink(arg: try! source()) // tainted | ||
|
||
sink(arg: (try? clean())!) | ||
sink(arg: (try? source())!) // tainted | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
|
||
class URL | ||
{ | ||
init?(string: String) {} | ||
init?(string: String, relativeTo: URL?) {} | ||
} | ||
|
||
func source() -> String { return "" } | ||
func sink(arg: URL) {} | ||
|
||
func taintThroughURL() { | ||
let clean = "http://example.com/" | ||
let tainted = source() | ||
let urlClean = URL(string: clean)! | ||
let urlTainted = URL(string: tainted)! | ||
|
||
sink(arg: urlClean) | ||
sink(arg: urlTainted) // tainted | ||
|
||
sink(arg: URL(string: clean, relativeTo: nil)!) | ||
sink(arg: URL(string: tainted, relativeTo: nil)!) // tainted | ||
sink(arg: URL(string: clean, relativeTo: urlClean)!) | ||
sink(arg: URL(string: clean, relativeTo: urlTainted)!) // tainted | ||
|
||
if let x = URL(string: clean) { | ||
sink(arg: x) | ||
} | ||
|
||
if let y = URL(string: tainted) { | ||
sink(arg: y) // tainted [NOT DETECTED] | ||
} | ||
|
||
var urlClean2 : URL! | ||
urlClean2 = URL(string: clean) | ||
sink(arg: urlClean2) | ||
|
||
var urlTainted2 : URL! | ||
urlTainted2 = URL(string: tainted) | ||
sink(arg: urlTainted2) // tainted | ||
} |