Skip to content

Commit 58a8739

Browse files
add taint steps for fields of String
if a String is tainted, then all its fields (including those declared in extensions) should be tainted as well
1 parent 4233c91 commit 58a8739

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import swift
2+
private import codeql.swift.dataflow.DataFlow
23
private import codeql.swift.dataflow.ExternalFlow
4+
private import codeql.swift.dataflow.FlowSteps
35

46
private class StringSource extends SourceModelCsv {
57
override predicate row(string row) {
@@ -16,3 +18,15 @@ private class StringSource extends SourceModelCsv {
1618
]
1719
}
1820
}
21+
22+
/**
23+
* A content implying that, if a `String` is tainted, then all its fields are tainted.
24+
*/
25+
private class StringFieldsInheritTaint extends TaintInheritingContent,
26+
DataFlow::Content::FieldContent {
27+
StringFieldsInheritTaint() {
28+
this.getField().getEnclosingDecl().(ClassOrStructDecl).getFullName() = "String" or
29+
this.getField().getEnclosingDecl().(ExtensionDecl).getExtendedTypeDecl().getFullName() =
30+
"String"
31+
}
32+
}

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,10 @@ func taintThroughStringOperations() {
8282
sink(arg: String(repeating: tainted, count: 2)) // $ MISSING: tainted=74
8383

8484
sink(arg: clean.description)
85-
sink(arg: tainted.description) // $ MISSING: tainted=74
85+
sink(arg: tainted.description) // $ tainted=74
8686

8787
sink(arg: clean.debugDescription)
88-
sink(arg: tainted.debugDescription) // $ MISSING: tainted=74
88+
sink(arg: tainted.debugDescription) // $ tainted=74
8989
}
9090

9191
class Data
@@ -111,3 +111,13 @@ func taintThroughData() {
111111
sink(arg: stringClean!)
112112
sink(arg: stringTainted!) // $ MISSING: tainted=100
113113
}
114+
115+
func sink(arg: String.UTF8View) {}
116+
117+
func taintThroughStringFields() {
118+
let clean = ""
119+
let tainted = source2().utf8
120+
121+
sink(arg: clean)
122+
sink(arg: tainted) // $ tainted=95
123+
}

0 commit comments

Comments
 (0)