@@ -7,6 +7,9 @@ private import codeql.swift.dataflow.DataFlow
7
7
private import codeql.swift.dataflow.ExternalFlow
8
8
private import codeql.swift.dataflow.FlowSteps
9
9
10
+ /**
11
+ * A model for `String` members that are sources of remote flow.
12
+ */
10
13
private class StringSource extends SourceModelCsv {
11
14
override predicate row ( string row ) {
12
15
row =
@@ -24,13 +27,122 @@ private class StringSource extends SourceModelCsv {
24
27
}
25
28
26
29
/**
27
- * A content implying that, if a `String` is tainted, then all its fields are tainted.
30
+ * A model for `String` and `StringProtocol` members that permit taint flow.
31
+ */
32
+ private class StringSummaries extends SummaryModelCsv {
33
+ override predicate row ( string row ) {
34
+ row =
35
+ [
36
+ ";StringProtocol;true;init(cString:);;;Argument[0];ReturnValue;taint" ,
37
+ ";StringProtocol;true;init(decoding:as:);;;Argument[0];ReturnValue;taint" ,
38
+ ";StringProtocol;true;init(decodingCString:as:);;;Argument[0];ReturnValue;taint" ,
39
+ ";StringProtocol;true;addingPercentEncoding(withAllowedCharacter:);;;Argument[-1];ReturnValue;taint" ,
40
+ ";StringProtocol;true;addingPercentEscapes(using:);;;Argument[-1];ReturnValue;taint" ,
41
+ ";StringProtocol;true;appending(_:);;;Argument[-1..0];ReturnValue;taint" ,
42
+ ";StringProtocol;true;appendingFormat(_:_:);;;Argument[-1..0];ReturnValue;taint" , //-1..
43
+ ";StringProtocol;true;applyingTransform(_:reverse:);;;Argument[-1];ReturnValue;taint" ,
44
+ ";StringProtocol;true;cString(using:);;;Argument[-1];ReturnValue;taint" ,
45
+ ";StringProtocol;true;capitalized(with:);;;Argument[-1];ReturnValue;taint" ,
46
+ ";StringProtocol;true;completePath(into:caseSensitive:matchesInto:filterTypes:);;;Argument[-1];Argument[0];taint" ,
47
+ ";StringProtocol;true;completePath(into:caseSensitive:matchesInto:filterTypes:);;;Argument[-1];Argument[2];taint" ,
48
+ ";StringProtocol;true;components(separatedBy:);;;Argument[-1];ReturnValue;taint" ,
49
+ ";StringProtocol;true;data(using:allowLossyConversion:);;;Argument[-1];ReturnValue;taint" ,
50
+ ";StringProtocol;true;folding(options:locale:);;;Argument[-1];ReturnValue;taint" ,
51
+ ";StringProtocol;true;getBytes(_:maxLength:usedLength:encoding:options:range:remaining:);;;Argument[-1];Argument[0];taint" ,
52
+ ";StringProtocol;true;getCString(_:maxLength:encoding:);;;Argument[-1];Argument[0];taint" ,
53
+ ";StringProtocol;true;lowercased();;;Argument[-1];ReturnValue;taint" ,
54
+ ";StringProtocol;true;lowercased(with:);;;Argument[-1];ReturnValue;taint" ,
55
+ ";StringProtocol;true;padding(toLength:withPad:startingAt:);;;Argument[-1];ReturnValue;taint" ,
56
+ ";StringProtocol;true;padding(toLength:withPad:startingAt:);;;Argument[1];ReturnValue;taint" ,
57
+ ";StringProtocol;true;propertyList();;;Argument[-1];ReturnValue;taint" ,
58
+ ";StringProtocol;true;propertyListFromStringsFileFormat();;;Argument[-1];ReturnValue;taint" ,
59
+ ";StringProtocol;true;replacingCharacters(in:with:);;;Argument[-1];ReturnValue;taint" ,
60
+ ";StringProtocol;true;replacingCharacters(in:with:);;;Argument[1];ReturnValue;taint" ,
61
+ ";StringProtocol;true;replacingOccurrences(of:with:options:range);;;Argument[-1];ReturnValue;taint" ,
62
+ ";StringProtocol;true;replacingOccurrences(of:with:options:range);;;Argument[1];ReturnValue;taint" ,
63
+ ";StringProtocol;true;replacingPercentEscapes(using:);;;Argument[-1];ReturnValue;taint" ,
64
+ ";StringProtocol;true;substring(from:);;;Argument[-1];ReturnValue;taint" ,
65
+ ";StringProtocol;true;substring(with:);;;Argument[-1];ReturnValue;taint" ,
66
+ ";StringProtocol;true;trimmingCharacters(in:);;;Argument[-1];ReturnValue;taint" ,
67
+ ";StringProtocol;true;uppercased();;;Argument[-1];ReturnValue;taint" ,
68
+ ";StringProtocol;true;uppercased(with:);;;Argument[-1];ReturnValue;taint" ,
69
+ ";String;true;init(decoding:);;;Argument[0];ReturnValue;taint" ,
70
+ ";String;true;init(_:);;;Argument[0];ReturnValue;taint" ,
71
+ ";String;true;init(repeating:count:);;;Argument[0];ReturnValue;taint" ,
72
+ ";String;true;init(data:encoding:);;;Argument[0];ReturnValue;taint" ,
73
+ ";String;true;init(validatingUTF8:);;;Argument[0];ReturnValue;taint" ,
74
+ ";String;true;init(utf16CodeUnits:count:);;;Argument[0];ReturnValue;taint" ,
75
+ ";String;true;init(utf16CodeUnitsNoCopy:count:freeWhenDone:);;;Argument[0];ReturnValue;taint" ,
76
+ ";String;true;init(format:_:);;;Argument[0];ReturnValue;taint" , //0..
77
+ ";String;true;init(format:arguments:);;;Argument[0..1];ReturnValue;taint" ,
78
+ ";String;true;init(format:locale:_:);;;Argument[0];ReturnValue;taint" , //0,2..
79
+ ";String;true;init(format:locale:arguments:);;;Argument[0];ReturnValue;taint" ,
80
+ ";String;true;init(_:radix:uppercase:);;;Argument[0];ReturnValue;taint" ,
81
+ ";String;true;init(bytes:encoding:);;;Argument[0];ReturnValue;taint" ,
82
+ ";String;true;init(bytesNoCopy:length:encoding:freeWhenDone);;;Argument[0];ReturnValue;taint" ,
83
+ ";String;true;init(describing:);;;Argument[0];ReturnValue;taint" ,
84
+ ";String;true;init(contentsOf:);;;Argument[0];ReturnValue;taint" ,
85
+ ";String;true;init(contentsOf:encoding:);;;Argument[0];ReturnValue;taint" ,
86
+ ";String;true;init(contendsOf:usedEncoding:);;;Argument[0];ReturnValue;taint" ,
87
+ ";String;true;init(contentsOfFile:);;;Argument[0];ReturnValue;taint" ,
88
+ ";String;true;init(contentsOfFile:encoding:);;;Argument[0];ReturnValue;taint" ,
89
+ ";String;true;init(contentsOfFile:usedEncoding:);;;Argument[0];ReturnValue;taint" ,
90
+ ";String;true;init(from:);;;Argument[0];ReturnValue;taint" ,
91
+ ";String;true;init(stringInterpolation:);;;Argument[0];ReturnValue;taint" ,
92
+ ";String;true;init(stringLiteral:);;;Argument[0];ReturnValue;taint" ,
93
+ ";String;true;init(unicodeScalarLiteral:);;;Argument[0];ReturnValue;taint" ,
94
+ ";String;true;init(extendedGraphemeClusterLiteral:);;;Argument[0];ReturnValue;taint" ,
95
+ ";String;true;init(cString:encoding:);;;Argument[0];ReturnValue;taint" ,
96
+ ";String;true;init(platformString:);;;Argument[0];ReturnValue;taint" ,
97
+ ";String;true;init(utf8String:);;;Argument[0];ReturnValue;taint" ,
98
+ ";String;true;init(validating:);;;Argument[0];ReturnValue;taint" ,
99
+ ";String;true;init(validatingPlatformString:);;;Argument[0];ReturnValue;taint" ,
100
+ ";String;true;localizedStringWithFormat(_:_:);;;Argument[0..1];ReturnValue;taint" ,
101
+ ";String;true;write(_:);;;Argument[0];Argument[-1];taint" ,
102
+ ";String;true;write(to:);;;Argument[-1];Argument[0];taint" ,
103
+ ";String;true;append(_:);;;Argument[0];Argument[-1];taint" ,
104
+ ";String;true;append(contentsOf:);;;Argument[0];Argument[-1];taint" ,
105
+ ";String;true;insert(_:at:);;;Argument[0];Argument[-1];taint" ,
106
+ ";String;true;insert(contentsOf:at:);;;Argument[0];Argument[-1];taint" ,
107
+ ";String;true;replaceSubrange(_:with::);;;Argument[1];Argument[-1];taint" ,
108
+ ";String;true;popLast();;;Argument[-1];ReturnValue;taint" ,
109
+ ";String;true;first(where:);;;Argument[-1];ReturnValue;taint" ,
110
+ ";String;true;last(where:);;;Argument[-1];ReturnValue;taint" ,
111
+ ";String;true;max();;;Argument[-1];ReturnValue;taint" ,
112
+ ";String;true;max(by:);;;Argument[-1];ReturnValue;taint" ,
113
+ ";String;true;min();;;Argument[-1];ReturnValue;taint" ,
114
+ ";String;true;min(by:);;;Argument[-1];ReturnValue;taint" ,
115
+ ";String;true;subscript(_:);;;Argument[-1];ReturnValue;taint" ,
116
+ ";String;true;split(maxSplits:omittingEmptySubsequences:whereSeparator:);;;Argument[-1];ReturnValue;taint" ,
117
+ ";String;true;randomElement();;;Argument[-1];ReturnValue;taint" ,
118
+ ";String;true;randomElement(using:);;;Argument[-1];ReturnValue;taint" ,
119
+ ";String;true;enumerated();;;Argument[-1];ReturnValue;taint" ,
120
+ ";String;true;encode(to:);;;Argument[-1];Argument[0];taint"
121
+ ]
122
+ }
123
+ }
124
+
125
+ /**
126
+ * A content implying that, if a `String` is tainted, then many of its fields are
127
+ * tainted. This also includes fields declared in `StringProtocol`.
28
128
*/
29
129
private class StringFieldsInheritTaint extends TaintInheritingContent ,
30
130
DataFlow:: Content:: FieldContent {
31
131
StringFieldsInheritTaint ( ) {
32
- this .getField ( ) .getEnclosingDecl ( ) .( ClassOrStructDecl ) .getFullName ( ) = "String" or
33
- this .getField ( ) .getEnclosingDecl ( ) .( ExtensionDecl ) .getExtendedTypeDecl ( ) .getFullName ( ) =
34
- "String"
132
+ exists ( FieldDecl f | this .getField ( ) = f |
133
+ (
134
+ f .getEnclosingDecl ( ) .( NominalTypeDecl ) .getName ( ) = [ "String" , "StringProtocol" ] or
135
+ f .getEnclosingDecl ( ) .( ExtensionDecl ) .getExtendedTypeDecl ( ) .getName ( ) =
136
+ [ "String" , "StringProtocol" ]
137
+ ) and
138
+ f .getName ( ) =
139
+ [
140
+ "first" , "last" , "unicodeScalars" , "utf8" , "utf16" , "lazy" , "utf8CString" , "description" ,
141
+ "debugDescription" , "dataValue" , "identifierValue" , "capitalized" , "localizedCapitalized" ,
142
+ "localizedLowercase" , "localizedUppercase" , "decomposedStringWithCanonicalMapping" ,
143
+ "decomposedStringWithCompatibilityMapping" , "precomposedStringWithCanonicalMapping" ,
144
+ "precomposedStringWithCompatibilityMapping" , "removingPercentEncoding"
145
+ ]
146
+ )
35
147
}
36
148
}
0 commit comments