@@ -32,32 +32,38 @@ class ApacheHttpRequest extends RefType {
32
32
class URLConstructor extends ClassInstanceExpr {
33
33
URLConstructor ( ) { this .getConstructor ( ) .getDeclaringType ( ) instanceof TypeUrl }
34
34
35
- // URLs constructed with the string constructor `URL(String spec)`
36
- Expr specArg ( ) {
35
+ predicate hasHttpStringArg ( ) {
37
36
this .getConstructor ( ) .getParameter ( 0 ) .getType ( ) instanceof TypeString and
38
37
(
38
+ // URLs constructed with the string constructor `URL(String spec)`
39
39
this .getConstructor ( ) .getNumberOfParameters ( ) = 1 and
40
- result = this .getArgument ( 0 ) // First argument contains the whole spec.
41
- )
42
- }
43
-
44
- // URLs constructed with any of the three string constructors below:
45
- // `URL(String protocol, String host, int port, String file)`,
46
- // `URL(String protocol, String host, int port, String file, URLStreamHandler handler)`,
47
- // `URL(String protocol, String host, String file)`
48
- Expr protocolArg ( ) {
49
- this .getConstructor ( ) .getParameter ( 0 ) .getType ( ) instanceof TypeString and
50
- (
40
+ this .getArgument ( 0 ) instanceof HttpString // First argument contains the whole spec.
41
+ or
42
+ // URLs constructed with any of the three string constructors below:
43
+ // `URL(String protocol, String host, int port, String file)`,
44
+ // `URL(String protocol, String host, int port, String file, URLStreamHandler handler)`,
45
+ // `URL(String protocol, String host, String file)`
51
46
this .getConstructor ( ) .getNumberOfParameters ( ) > 1 and
52
- result = this .getArgument ( 0 ) // First argument contains the protocol part.
47
+ concatHttpString ( getArgument ( 0 ) , this .getArgument ( 1 ) ) // First argument contains the protocol part and the second argument contains the host part.
53
48
)
54
49
}
50
+ }
55
51
56
- Expr hostArg ( ) {
57
- this .getConstructor ( ) .getParameter ( 0 ) .getType ( ) instanceof TypeString and
52
+ /**
53
+ * Class of Java URI constructor.
54
+ */
55
+ class URIConstructor extends ClassInstanceExpr {
56
+ URIConstructor ( ) { this .getConstructor ( ) .getDeclaringType ( ) .hasQualifiedName ( "java.net" , "URI" ) }
57
+
58
+ predicate hasHttpStringArg ( ) {
58
59
(
59
- this .getConstructor ( ) .getNumberOfParameters ( ) > 1 and
60
- result = this .getArgument ( 1 ) // Second argument contains the host part.
60
+ this .getNumArgument ( ) = 1 // `URI(String str)`
61
+ or
62
+ this .getNumArgument ( ) = 4 and
63
+ concatHttpString ( this .getArgument ( 0 ) , this .getArgument ( 1 ) ) // `URI(String scheme, String host, String path, String fragment)`
64
+ or
65
+ this .getNumArgument ( ) = 7 and
66
+ concatHttpString ( this .getArgument ( 0 ) , this .getArgument ( 2 ) ) // `URI(String scheme, String userInfo, String host, int port, String path, String query, String fragment)`
61
67
)
62
68
}
63
69
}
@@ -66,7 +72,7 @@ class URLConstructor extends ClassInstanceExpr {
66
72
* Gets a regular expression for matching private hosts.
67
73
*/
68
74
private string getPrivateHostRegex ( ) {
69
- result = "localhost(/.*)?" or
75
+ result = "(?i) localhost(/.*)?" or
70
76
result = "127\\.0\\.0\\.1(/.*)?" or // IPv4 patterns
71
77
result = "10(\\.[0-9]+){3}(/.*)?" or
72
78
result = "172\\.16(\\.[0-9]+){2}(/.*)?" or
@@ -78,13 +84,11 @@ private string getPrivateHostRegex() {
78
84
/**
79
85
* String of HTTP URLs not in private domains.
80
86
*/
81
- class HttpString extends StringLiteral {
82
- HttpString ( ) {
87
+ class HttpStringLiteral extends StringLiteral {
88
+ HttpStringLiteral ( ) {
83
89
// Match URLs with the HTTP protocol and without private IP addresses to reduce false positives.
84
90
exists ( string s | this .getRepresentedString ( ) = s |
85
- s .regexpMatch ( "(?i)http" )
86
- or
87
- s .regexpMatch ( "(?i)http://.*" ) and
91
+ s .regexpMatch ( "(?i)http://[a-zA-Z0-9].*" ) and
88
92
not s .substring ( 7 , s .length ( ) ) .regexpMatch ( getPrivateHostRegex ( ) )
89
93
)
90
94
}
@@ -117,20 +121,22 @@ predicate concatHttpString(Expr protocol, Expr host) {
117
121
}
118
122
119
123
/**
120
- * String concatenated with `HttpString `.
124
+ * String concatenated with `HttpStringLiteral `.
121
125
*/
122
- predicate builtFromHttpStringConcat ( Expr expr ) {
123
- expr instanceof HttpString
124
- or
125
- expr .( VarAccess ) .getVariable ( ) .getAnAssignedValue ( ) instanceof HttpString
126
- or
127
- concatHttpString ( expr .( AddExpr ) .getLeftOperand ( ) , expr .( AddExpr ) .getRightOperand ( ) )
128
- or
129
- concatHttpString ( expr .( AddExpr ) .getLeftOperand ( ) .( AddExpr ) .getLeftOperand ( ) ,
130
- expr .( AddExpr ) .getLeftOperand ( ) .( AddExpr ) .getRightOperand ( ) )
131
- or
132
- concatHttpString ( expr .( AddExpr ) .getLeftOperand ( ) ,
133
- expr .( AddExpr ) .getRightOperand ( ) .( AddExpr ) .getLeftOperand ( ) )
126
+ class HttpString extends Expr {
127
+ HttpString ( ) {
128
+ this instanceof HttpStringLiteral
129
+ or
130
+ this .( VarAccess ) .getVariable ( ) .getAnAssignedValue ( ) instanceof HttpStringLiteral
131
+ or
132
+ concatHttpString ( this .( AddExpr ) .getLeftOperand ( ) , this .( AddExpr ) .getRightOperand ( ) )
133
+ or
134
+ concatHttpString ( this .( AddExpr ) .getLeftOperand ( ) .( AddExpr ) .getLeftOperand ( ) ,
135
+ this .( AddExpr ) .getLeftOperand ( ) .( AddExpr ) .getRightOperand ( ) )
136
+ or
137
+ concatHttpString ( this .( AddExpr ) .getLeftOperand ( ) ,
138
+ this .( AddExpr ) .getRightOperand ( ) .( AddExpr ) .getLeftOperand ( ) ) // First two elements of a string concatenated from an arbitrary number of elements.
139
+ }
134
140
}
135
141
136
142
/**
@@ -161,10 +167,76 @@ class HttpURLOpenMethod extends Method {
161
167
}
162
168
}
163
169
170
+ /** Constructor of `ApacheHttpRequest` */
171
+ predicate apacheHttpRequest ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
172
+ exists ( ConstructorCall cc |
173
+ cc .getConstructedType ( ) instanceof ApacheHttpRequest and
174
+ node2 .asExpr ( ) = cc and
175
+ cc .getAnArgument ( ) = node1 .asExpr ( )
176
+ )
177
+ }
178
+
179
+ /** Constructors of `URI` */
180
+ predicate createURI ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
181
+ exists ( URIConstructor cc |
182
+ node2 .asExpr ( ) = cc and
183
+ cc .getArgument ( 0 ) = node1 .asExpr ( ) and
184
+ cc .hasHttpStringArg ( )
185
+ )
186
+ or
187
+ exists (
188
+ StaticMethodAccess ma // URI.create
189
+ |
190
+ ma .getMethod ( ) .getDeclaringType ( ) .hasQualifiedName ( "java.net" , "URI" ) and
191
+ ma .getMethod ( ) .hasName ( "create" ) and
192
+ node1 .asExpr ( ) = ma .getArgument ( 0 ) and
193
+ node2 .asExpr ( ) = ma
194
+ )
195
+ }
196
+
197
+ /** Constructors of `URL` */
198
+ predicate createURL ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
199
+ exists ( URLConstructor cc |
200
+ node2 .asExpr ( ) = cc and
201
+ cc .getArgument ( 0 ) = node1 .asExpr ( ) and
202
+ cc .hasHttpStringArg ( )
203
+ )
204
+ }
205
+
206
+ /** Method call of `HttpURLOpenMethod` */
207
+ predicate urlOpen ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
208
+ exists ( MethodAccess ma |
209
+ ma .getMethod ( ) instanceof HttpURLOpenMethod and
210
+ node1 .asExpr ( ) = ma .getQualifier ( ) and
211
+ ma = node2 .asExpr ( )
212
+ )
213
+ }
214
+
215
+ /** Constructor of `BasicRequestLine` */
216
+ predicate basicRequestLine ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
217
+ exists ( ConstructorCall mcc |
218
+ mcc .getConstructedType ( ) .hasQualifiedName ( "org.apache.http.message" , "BasicRequestLine" ) and
219
+ mcc .getArgument ( 1 ) = node1 .asExpr ( ) and // `BasicRequestLine(String method, String uri, ProtocolVersion version)
220
+ node2 .asExpr ( ) = mcc
221
+ )
222
+ }
223
+
164
224
class BasicAuthFlowConfig extends TaintTracking:: Configuration {
165
225
BasicAuthFlowConfig ( ) { this = "InsecureBasicAuth::BasicAuthFlowConfig" }
166
226
167
- override predicate isSource ( DataFlow:: Node src ) { src .asExpr ( ) instanceof HttpString }
227
+ override predicate isSource ( DataFlow:: Node src ) {
228
+ src .asExpr ( ) instanceof HttpString
229
+ or
230
+ exists ( URLConstructor uc |
231
+ uc .hasHttpStringArg ( ) and
232
+ src .asExpr ( ) = uc .getArgument ( 0 )
233
+ )
234
+ or
235
+ exists ( URIConstructor uc |
236
+ uc .hasHttpStringArg ( ) and
237
+ src .asExpr ( ) = uc .getArgument ( 0 )
238
+ )
239
+ }
168
240
169
241
override predicate isSink ( DataFlow:: Node sink ) {
170
242
exists ( MethodAccess ma |
@@ -180,81 +252,11 @@ class BasicAuthFlowConfig extends TaintTracking::Configuration {
180
252
}
181
253
182
254
override predicate isAdditionalTaintStep ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
183
- exists ( ConstructorCall cc |
184
- cc .getConstructedType ( ) instanceof ApacheHttpRequest and
185
- node2 .asExpr ( ) = cc and
186
- (
187
- cc .getAnArgument ( ) = node1 .asExpr ( ) and
188
- builtFromHttpStringConcat ( cc .getAnArgument ( ) )
189
- or
190
- exists ( ConstructorCall mcc |
191
- (
192
- mcc .getConstructedType ( ) .hasQualifiedName ( "org.apache.http.message" , "BasicRequestLine" ) and
193
- mcc .getArgument ( 1 ) = node1 .asExpr ( ) and // `BasicRequestLine(String method, String uri, ProtocolVersion version)
194
- builtFromHttpStringConcat ( mcc .getArgument ( 1 ) )
195
- or
196
- mcc .getConstructedType ( ) .hasQualifiedName ( "java.net" , "URI" ) and
197
- (
198
- mcc .getNumArgument ( ) = 1 and
199
- mcc .getArgument ( 0 ) = node1 .asExpr ( ) and
200
- builtFromHttpStringConcat ( mcc .getArgument ( 0 ) ) // `URI(String str)`
201
- or
202
- mcc .getNumArgument ( ) = 4 and
203
- mcc .getArgument ( 0 ) = node1 .asExpr ( ) and
204
- concatHttpString ( mcc .getArgument ( 0 ) , mcc .getArgument ( 1 ) ) // `URI(String scheme, String host, String path, String fragment)`
205
- or
206
- mcc .getNumArgument ( ) = 7 and
207
- mcc .getArgument ( 0 ) = node1 .asExpr ( ) and
208
- concatHttpString ( mcc .getArgument ( 2 ) , mcc .getArgument ( 1 ) ) // `URI(String scheme, String userInfo, String host, int port, String path, String query, String fragment)`
209
- )
210
- ) and
211
- (
212
- cc .getAnArgument ( ) = mcc
213
- or
214
- exists ( VarAccess va |
215
- cc .getAnArgument ( ) = va and va .getVariable ( ) .getAnAssignedValue ( ) = mcc
216
- )
217
- )
218
- )
219
- or
220
- exists ( StaticMethodAccess ma |
221
- ma .getMethod ( ) .getDeclaringType ( ) .hasQualifiedName ( "java.net" , "URI" ) and
222
- ma .getMethod ( ) .hasName ( "create" ) and
223
- builtFromHttpStringConcat ( ma .getArgument ( 0 ) ) and
224
- node1 .asExpr ( ) = ma .getArgument ( 0 ) and
225
- (
226
- cc .getArgument ( 0 ) = ma
227
- or
228
- exists ( VarAccess va |
229
- cc .getArgument ( 0 ) = va and va .getVariable ( ) .getAnAssignedValue ( ) = ma
230
- )
231
- )
232
- )
233
- )
234
- )
235
- or
236
- exists ( MethodAccess ma |
237
- ma .getMethod ( ) instanceof HttpURLOpenMethod and
238
- ma = node2 .asExpr ( ) and
239
- (
240
- node1 .asExpr ( ) = ma .getQualifier ( ) .( URLConstructor ) .getArgument ( 0 ) and
241
- (
242
- builtFromHttpStringConcat ( ma .getQualifier ( ) .( URLConstructor ) .specArg ( ) ) or
243
- concatHttpString ( ma .getQualifier ( ) .( URLConstructor ) .protocolArg ( ) ,
244
- ma .getQualifier ( ) .( URLConstructor ) .hostArg ( ) )
245
- )
246
- or
247
- exists ( URLConstructor uc , VarAccess va |
248
- node1 .asExpr ( ) = uc .getAnArgument ( ) and
249
- uc = va .getVariable ( ) .getAnAssignedValue ( ) and
250
- ma .getQualifier ( ) = va and
251
- (
252
- builtFromHttpStringConcat ( uc .specArg ( ) ) or
253
- concatHttpString ( uc .protocolArg ( ) , uc .hostArg ( ) )
254
- )
255
- )
256
- )
257
- )
255
+ apacheHttpRequest ( node1 , node2 ) or
256
+ createURI ( node1 , node2 ) or
257
+ basicRequestLine ( node1 , node2 ) or
258
+ createURL ( node1 , node2 ) or
259
+ urlOpen ( node1 , node2 )
258
260
}
259
261
}
260
262
0 commit comments