File tree Expand file tree Collapse file tree 3 files changed +24
-5
lines changed
lib/semmle/code/java/frameworks/spring
test/query-tests/security/CWE-079/semmle/tests Expand file tree Collapse file tree 3 files changed +24
-5
lines changed Original file line number Diff line number Diff line change @@ -121,9 +121,18 @@ class SpringRequestMappingMethod extends SpringControllerMethod {
121
121
SpringRequestMappingParameter getARequestParameter ( ) { result = getAParameter ( ) }
122
122
123
123
/** Gets the "produces" @RequestMapping annotation value, if present. */
124
+ Expr getProducesExpr ( ) { result = requestMappingAnnotation .getValue ( "produces" ) }
125
+
126
+ /** Gets the "produces" @RequestMapping annotation value, if present. */
127
+ Expr getAProducesExpr ( ) {
128
+ result = this .getProducesExpr ( ) and not result instanceof ArrayInit
129
+ or
130
+ result = this .getProducesExpr ( ) .( ArrayInit ) .getAnInit ( )
131
+ }
132
+
133
+ /** Gets the "produces" @RequestMapping annotation value, if present and a string constant. */
124
134
string getProduces ( ) {
125
- result =
126
- requestMappingAnnotation .getValue ( "produces" ) .( CompileTimeConstantExpr ) .getStringValue ( )
135
+ result = this .getProducesExpr ( ) .( CompileTimeConstantExpr ) .getStringValue ( )
127
136
}
128
137
129
138
/** Gets the "value" @RequestMapping annotation value, if present. */
Original file line number Diff line number Diff line change @@ -145,14 +145,19 @@ private class SpringHttpFlowStep extends SummaryModelCsv {
145
145
}
146
146
}
147
147
148
+ private predicate specifiesContentType ( SpringRequestMappingMethod method ) {
149
+ method .getProducesExpr ( ) .( ArrayInit ) .getSize ( ) != 0 or
150
+ not method .getProducesExpr ( ) instanceof ArrayInit
151
+ }
152
+
148
153
private class SpringXssSink extends XSS:: XssSink {
149
154
SpringXssSink ( ) {
150
155
exists ( SpringRequestMappingMethod requestMappingMethod , ReturnStmt rs |
151
156
requestMappingMethod = rs .getEnclosingCallable ( ) and
152
157
this .asExpr ( ) = rs .getResult ( ) and
153
158
(
154
- not exists ( requestMappingMethod . getProduces ( ) ) or
155
- requestMappingMethod .getProduces ( ) . matches ( "text/%" )
159
+ not specifiesContentType ( requestMappingMethod ) or
160
+ isXssVulnerableContentTypeExpr ( requestMappingMethod .getAProducesExpr ( ) )
156
161
)
157
162
|
158
163
// If a Spring request mapping method is either annotated with @ResponseBody (or equivalent),
@@ -251,6 +256,11 @@ private string getSpringConstantContentType(FieldAccess e) {
251
256
)
252
257
}
253
258
259
+ private predicate isXssVulnerableContentTypeExpr ( Expr e ) {
260
+ XSS:: isXssVulnerableContentType ( e .( CompileTimeConstantExpr ) .getStringValue ( ) ) or
261
+ XSS:: isXssVulnerableContentType ( getSpringConstantContentType ( e ) )
262
+ }
263
+
254
264
private predicate isXssSafeContentTypeExpr ( Expr e ) {
255
265
XSS:: isXssSafeContentType ( e .( CompileTimeConstantExpr ) .getStringValue ( ) ) or
256
266
XSS:: isXssSafeContentType ( getSpringConstantContentType ( e ) )
Original file line number Diff line number Diff line change @@ -60,7 +60,7 @@ public static ResponseEntity<String> methodContentTypeSafeStringLiteral(String u
60
60
61
61
@ GetMapping (value = "/xyz" , produces = MediaType .TEXT_HTML_VALUE )
62
62
public static ResponseEntity <String > methodContentTypeUnsafe (String userControlled ) {
63
- return ResponseEntity .ok (userControlled ); // $MISSING: xss
63
+ return ResponseEntity .ok (userControlled ); // $xss
64
64
}
65
65
66
66
@ GetMapping (value = "/xyz" , produces = "text/html" )
You can’t perform that action at this time.
0 commit comments