@@ -19,12 +19,10 @@ class SpringControllerAnnotation extends AnnotationType {
19
19
/**
20
20
* An annotation type that identifies Spring rest controllers.
21
21
*
22
- * Rest controllers are the same as controllers, but imply the @ResponseBody annotation.
22
+ * Rest controllers are the same as controllers, but imply the ` @ResponseBody` annotation.
23
23
*/
24
24
class SpringRestControllerAnnotation extends SpringControllerAnnotation {
25
- SpringRestControllerAnnotation ( ) {
26
- hasName ( "RestController" )
27
- }
25
+ SpringRestControllerAnnotation ( ) { hasName ( "RestController" ) }
28
26
}
29
27
30
28
/**
@@ -80,7 +78,7 @@ class SpringInitBinderMethod extends SpringControllerMethod {
80
78
}
81
79
82
80
/**
83
- * An `AnnotationType` which is used to indicate a `RequestMapping`.
81
+ * An `AnnotationType` that is used to indicate a `RequestMapping`.
84
82
*/
85
83
class SpringRequestMappingAnnotationType extends AnnotationType {
86
84
SpringRequestMappingAnnotationType ( ) {
@@ -93,7 +91,7 @@ class SpringRequestMappingAnnotationType extends AnnotationType {
93
91
}
94
92
95
93
/**
96
- * An `AnnotationType` which is used to indicate a `ResponseBody`.
94
+ * An `AnnotationType` that is used to indicate a `ResponseBody`.
97
95
*/
98
96
class SpringResponseBodyAnnotationType extends AnnotationType {
99
97
SpringResponseBodyAnnotationType ( ) {
@@ -107,6 +105,7 @@ class SpringResponseBodyAnnotationType extends AnnotationType {
107
105
*/
108
106
class SpringRequestMappingMethod extends SpringControllerMethod {
109
107
Annotation requestMappingAnnotation ;
108
+
110
109
SpringRequestMappingMethod ( ) {
111
110
// Any method that declares the @RequestMapping annotation, or overrides a method that declares
112
111
// the annotation. We have to do this explicit check because the @RequestMapping annotation is
@@ -119,21 +118,18 @@ class SpringRequestMappingMethod extends SpringControllerMethod {
119
118
}
120
119
121
120
/** Gets a request mapping parameter. */
122
- SpringRequestMappingParameter getARequestParameter ( ) {
123
- result = getAParameter ( )
124
- }
121
+ SpringRequestMappingParameter getARequestParameter ( ) { result = getAParameter ( ) }
125
122
126
123
/** Gets the "produces" @RequestMapping annotation value, if present. */
127
124
string getProduces ( ) {
128
- result = requestMappingAnnotation .getValue ( "produces" ) .( CompileTimeConstantExpr ) .getStringValue ( )
125
+ result =
126
+ requestMappingAnnotation .getValue ( "produces" ) .( CompileTimeConstantExpr ) .getStringValue ( )
129
127
}
130
128
131
- /** Holds if this is considered an @ResponseBody method. */
129
+ /** Holds if this is considered an ` @ResponseBody` method. */
132
130
predicate isResponseBody ( ) {
133
- getAnAnnotation ( ) .getType ( ) instanceof SpringResponseBodyAnnotationType
134
- or
135
- getDeclaringType ( ) .getAnAnnotation ( ) .getType ( ) instanceof SpringResponseBodyAnnotationType
136
- or
131
+ getAnAnnotation ( ) .getType ( ) instanceof SpringResponseBodyAnnotationType or
132
+ getDeclaringType ( ) .getAnAnnotation ( ) .getType ( ) instanceof SpringResponseBodyAnnotationType or
137
133
getDeclaringType ( ) instanceof SpringRestController
138
134
}
139
135
}
@@ -156,12 +152,14 @@ class SpringServletInputAnnotation extends Annotation {
156
152
}
157
153
}
158
154
155
+ /** An annotation of the type `org.springframework.web.bind.annotation.ModelAttribute`. */
159
156
class SpringModelAttributeAnnotation extends Annotation {
160
157
SpringModelAttributeAnnotation ( ) {
161
158
getType ( ) .hasQualifiedName ( "org.springframework.web.bind.annotation" , "ModelAttribute" )
162
159
}
163
160
}
164
161
162
+ /** A parameter of a `SpringRequestMappingMethod`. */
165
163
class SpringRequestMappingParameter extends Parameter {
166
164
SpringRequestMappingParameter ( ) { getCallable ( ) instanceof SpringRequestMappingMethod }
167
165
@@ -180,29 +178,47 @@ class SpringRequestMappingParameter extends Parameter {
180
178
getType ( ) .( RefType ) .getAnAncestor ( ) .hasQualifiedName ( "java.time" , "ZoneId" ) or
181
179
getType ( ) .( RefType ) .getAnAncestor ( ) .hasQualifiedName ( "java.io" , "OutputStream" ) or
182
180
getType ( ) .( RefType ) .getAnAncestor ( ) .hasQualifiedName ( "java.io" , "Writer" ) or
183
- getType ( ) .( RefType ) .getAnAncestor ( ) .hasQualifiedName ( "org.springframework.web.servlet.mvc.support" , "RedirectAttributes" ) or
181
+ getType ( )
182
+ .( RefType )
183
+ .getAnAncestor ( )
184
+ .hasQualifiedName ( "org.springframework.web.servlet.mvc.support" , "RedirectAttributes" ) or
184
185
// Also covers BindingResult. Note, you can access the field value through this interface, which should be considered tainted
185
186
getType ( ) .( RefType ) .getAnAncestor ( ) .hasQualifiedName ( "org.springframework.validation" , "Errors" ) or
186
- getType ( ) .( RefType ) .getAnAncestor ( ) .hasQualifiedName ( "org.springframework.web.bind.support" , "SessionStatus" ) or
187
- getType ( ) .( RefType ) .getAnAncestor ( ) .hasQualifiedName ( "org.springframework.web.util" , "UriComponentsBuilder" ) or
188
- getType ( ) .( RefType ) .getAnAncestor ( ) .hasQualifiedName ( "org.springframework.data.domain" , "Pageable" ) or
187
+ getType ( )
188
+ .( RefType )
189
+ .getAnAncestor ( )
190
+ .hasQualifiedName ( "org.springframework.web.bind.support" , "SessionStatus" ) or
191
+ getType ( )
192
+ .( RefType )
193
+ .getAnAncestor ( )
194
+ .hasQualifiedName ( "org.springframework.web.util" , "UriComponentsBuilder" ) or
195
+ getType ( )
196
+ .( RefType )
197
+ .getAnAncestor ( )
198
+ .hasQualifiedName ( "org.springframework.data.domain" , "Pageable" ) or
189
199
this instanceof SpringModel
190
200
}
191
201
192
- predicate isExplicitlyTaintedInput ( ) {
202
+ private predicate isExplicitlyTaintedInput ( ) {
193
203
// InputStream or Reader parameters allow access to the body of a request
194
204
getType ( ) .( RefType ) .getAnAncestor ( ) .hasQualifiedName ( "java.io" , "InputStream" ) or
195
205
getType ( ) .( RefType ) .getAnAncestor ( ) .hasQualifiedName ( "java.io" , "Reader" ) or
196
206
// The SpringServletInputAnnotations allow access to the URI, request parameters, cookie values and the body of the request
197
207
this .getAnAnnotation ( ) instanceof SpringServletInputAnnotation or
198
208
// HttpEntity is like @RequestBody, but with a wrapper including the headers
199
209
// TODO model unwrapping aspects
200
- getType ( ) .( RefType ) .getAnAncestor ( ) .hasQualifiedName ( "org.springframework.http" , "HttpEntity<T>" ) or
201
- this .getAnAnnotation ( ) .getType ( ) .hasQualifiedName ( "org.springframework.web.bind.annotation" , "RequestAttribute" ) or
202
- this .getAnAnnotation ( ) .getType ( ) .hasQualifiedName ( "org.springframework.web.bind.annotation" , "SessionAttribute" )
210
+ getType ( ) .( RefType ) .getASourceSupertype * ( ) instanceof SpringHttpEntity or
211
+ this
212
+ .getAnAnnotation ( )
213
+ .getType ( )
214
+ .hasQualifiedName ( "org.springframework.web.bind.annotation" , "RequestAttribute" ) or
215
+ this
216
+ .getAnAnnotation ( )
217
+ .getType ( )
218
+ .hasQualifiedName ( "org.springframework.web.bind.annotation" , "SessionAttribute" )
203
219
}
204
220
205
- predicate isImplicitRequestParam ( ) {
221
+ private predicate isImplicitRequestParam ( ) {
206
222
// Any parameter which is not explicitly handled, is consider to be an `@RequestParam`, if
207
223
// it is a simple bean property
208
224
not isNotDirectlyTaintedInput ( ) and
@@ -213,23 +229,24 @@ class SpringRequestMappingParameter extends Parameter {
213
229
)
214
230
}
215
231
216
- predicate isImplicitModelAttribute ( ) {
232
+ private predicate isImplicitModelAttribute ( ) {
217
233
// Any parameter which is not explicitly handled, is consider to be an `@ModelAttribute`, if
218
234
// it is not an implicit request param
219
235
not isNotDirectlyTaintedInput ( ) and
220
236
not isExplicitlyTaintedInput ( ) and
221
237
not isImplicitRequestParam ( )
222
238
}
223
239
224
- /** Holds if this is an explicit or implicit @ModelAttribute parameter */
240
+ /** Holds if this is an explicit or implicit ` @ModelAttribute` parameter. */
225
241
predicate isModelAttribute ( ) {
226
242
isImplicitModelAttribute ( ) or
227
243
getAnAnnotation ( ) instanceof SpringModelAttributeAnnotation
228
244
}
229
245
230
- /** Holds if the input is tainted */
246
+ /** Holds if the input is tainted. */
231
247
predicate isTaintedInput ( ) {
232
- isExplicitlyTaintedInput ( ) or
248
+ isExplicitlyTaintedInput ( )
249
+ or
233
250
// Any parameter which is not explicitly identified, is consider to be an `@RequestParam`, if
234
251
// it is a simple bean property) or a @ModelAttribute if not
235
252
not isNotDirectlyTaintedInput ( )
@@ -305,18 +322,18 @@ private RefType stripType(Type t) {
305
322
}
306
323
307
324
/**
308
- * A user data type which may be populated from a HTTP request.
325
+ * A user data type that may be populated from an HTTP request.
309
326
*
310
- * This includes types directly referred to as either @ModelAttribute or @RequestBody parameters,
311
- * or types which are referred to by those types.
327
+ * This includes types directly referred to as either ` @ModelAttribute` or ` @RequestBody` parameters,
328
+ * or types that are referred to by those types.
312
329
*/
313
330
class SpringUntrustedDataType extends RefType {
314
331
SpringUntrustedDataType ( ) {
315
332
exists ( SpringRequestMappingParameter p |
316
333
p .isModelAttribute ( )
317
334
or
318
335
p .getAnAnnotation ( ) .( SpringServletInputAnnotation ) .getType ( ) .hasName ( "RequestBody" )
319
- |
336
+ |
320
337
this .fromSource ( ) and
321
338
this = stripType ( p .getType ( ) )
322
339
)
0 commit comments