@@ -7,6 +7,9 @@ private import codeql.swift.dataflow.DataFlow
77private import codeql.swift.dataflow.ExternalFlow
88private import codeql.swift.dataflow.FlowSteps
99
10+ /**
11+ * A model for `String` members that are sources of remote flow.
12+ */
1013private class StringSource extends SourceModelCsv {
1114 override predicate row ( string row ) {
1215 row =
@@ -24,13 +27,122 @@ private class StringSource extends SourceModelCsv {
2427}
2528
2629/**
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`.
28128 */
29129private class StringFieldsInheritTaint extends TaintInheritingContent ,
30130 DataFlow:: Content:: FieldContent {
31131 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+ )
35147 }
36148}
0 commit comments